如何向 Pandas Series 添加单个元素?

107

我该如何向 Pandas 的 Series 实例中添加单个元素?

我需要类似以下这样的代码:

>>> x = Series()
>>> N = 4
>>> for i in xrange(N):
>>>     x.some_appending_function(i**2)    
>>> print(x)
0 | 0
1 | 1
2 | 4
3 | 9

同样地,我如何向Pandas DataFrame添加单个行?


相关:如何创建一个空的 Pandas DataFrame,然后填充它? - 简而言之,在最后将列表转换为序列。 - cs95
8个回答

52

如何添加单个项目。这种方法并不是非常高效,但可以按照您的要求进行操作:

x = p.Series()
N = 4
for i in xrange(N):
   x = x.set_value(i, i**2)

生成 x:

0    0
1    1
2    4
3    9

显然有更好的方法一次性生成这个系列。

对于您的第二个问题,请查看SO问题的答案和参考资料add one row in a pandas.DataFrame


你使用的 pandas 版本是多少?我使用的是 0.14.1,但出现了下面的错误:IndexError: index 0 is out of bounds for axis 0 with size 0 - Ben
@Ben,不确定,答案已经超过2年了。我用0.15.0进行了测试,它完美地工作了。你是否执行了完全相同的代码 - joaquin
是的,我刚刚将代码直接粘贴到一个新的控制台中。奇怪的是,它现在似乎可以工作了! - Ben
1
在Python > 3中,您不需要使用x = x.set_value(i, i**2),因为x.set_value()会直接更改x - jeongmin.cha
26
是的,set_value()已被弃用。请使用x.at[i] = i**2或者x.iat[i] = i**2 - Wolfgang Kuehn
@WolfgangKuehn 我想知道为什么在空系列中执行 x[i] = 'some value' 会出错,但在 x.at[i] 的情况下却可以正常工作? series.at[] 的文档也没有提到这方面的任何内容,我认为他们应该加上! - amsquareb

51

简而言之,不要逐个添加序列项,最好使用有序集合进行扩展

In [1]: import pandas as pd
In [2]: import numpy as np

In [3]: s = pd.Series(np.arange(4)**2, index=np.arange(4))

In [4]: s
Out[4]:
0    0
1    1
2    4
3    9
dtype: int64

In [6]: id(s.index), id(s.values)
Out[6]: (4470549648, 4470593296)

当我们更新现有项时,如果您不更改值的类型,则索引和值数组保持不变。

In [7]: s[2] = 14  

In [8]: id(s.index), id(s.values)
Out[8]: (4470549648, 4470593296)

但是当您添加一个新项时,会生成一个新的索引和一个新的值数组:

In [9]: s[4] = 16

In [10]: s
Out[10]:
0     0
1     1
2    14
3     9
4    16
dtype: int64

In [11]: id(s.index), id(s.values)
Out[11]: (4470548560, 4470595056)

如果您要追加多个项目,可以将它们收集到字典中,创建一个Series,将其附加到旧的Series并保存结果:

In [13]: new_items = {item: item**2 for item in range(5, 7)}

In [14]: s2 = pd.Series(new_items)

In [15]: s2  # keys are guaranteed to be sorted!
Out[15]:
5    25
6    36
dtype: int64

In [16]: s = s.append(s2); s
Out[16]:
0     0
1     1
2    14
3     9
4    16
5    25
6    36
dtype: int64

应该注意到 append 返回一个新的变量,而赋值则直接修改了数据框。虽然所有底层都在改变,但引用是相同的。 - anishtain4

48
如果您有索引和值,则可以按如下方式将其添加到Series中:
obj = Series([4,7,-5,3])
obj.index=['a', 'b', 'c', 'd']

obj['e'] = 181

这将向Series添加一个新值(在Series末尾)。


4
很棒的回答,简短明了。 - Brian Wylie
4
这是最好的答案。 - boardtc

15

您可以使用append函数将另一个元素添加到其中。只需在将其附加之前创建一系列新元素:

test = test.append(pd.Series(200, index=[101]))

3
我认为append()方法会返回一个新的Series(而不是原地修改),所以你需要使用test = test.append(pd.Series(200, index=[101]))来更新它。 - A.Wan
1
@A.Wan,是的,我应该更清楚地表达。谢谢! - fixxxer
我更喜欢这种方法,而不是test.at[i] = i**2方法,因为那种方法似乎会按字母顺序插入新值,而这种方法直接将值附加到末尾,这正是我想要的。 - Veggiet

9
关于@joaqin的solution已被弃用,因为"set_value"方法将在未来的pandas版本中删除,我想提及另一个选项,使用".at[]"访问器向pandas系列添加单个项目。
>>> import pandas as pd
>>> x = pd.Series()
>>> N = 4
>>> for i in range(N):
...     x.at[i] = i**2

它产生相同的输出。
>>> print(x)
0    0
1    1
2    4
3    9

6
补充joquin的回答,以下表单可能会更加简洁(至少更易读):
x = p.Series()
N = 4
for i in xrange(N):
   x[i] = i**2

此外,如果您只想在末尾添加一个单一元素,可以采用有点非正统的方法:
x = p.Series()
value_to_append = 5
x[len(x)] = value_to_append

代码的第二部分在Python 3中无法正常工作。 - M. Chavoshi

3
import pandas as pd
import numpy as np

ser1 = pd.Series(np.linspace(1, 10, 2))
element = np.nan
ser1 = ser1.append(pd.Series(element))

0

这里有另一个想法n,可以在不更改系列名称的情况下在一行中附加多个项目。但是,这可能不像其他答案那样有效。

>>> df = pd.Series(np.random.random(5), name='random')
>>> df

0    0.363885
1    0.402623
2    0.450449
3    0.172917
4    0.983481
Name: random, dtype: float64


>>> df.to_frame().T.assign(a=3, b=2, c=5).squeeze()

0    0.363885
1    0.402623
2    0.450449
3    0.172917
4    0.983481
a    3.000000
b    2.000000
c    5.000000
Name: random, dtype: float64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接