如何将单个项目添加到熊猫系列


76

如何将单个项目添加到序列化的熊猫系列中。我知道这不是最有效的内存管理方式,但是我仍然需要这样做。

沿途:

>> 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,然后填充它?-TLDR建立一个列表,然后在最后转换为系列。
cs95

Answers:


45

如何添加单个项目。这不是很有效,但是遵循您的要求:

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问题的引用在pandas.DataFrame中添加一行


您使用的是哪个版本的熊猫?我正在使用0.14.1,并且收到以下错误:IndexError: index 0 is out of bounds for axis 0 with size 0
本钟

@Ben,不确定,答案已超过2岁。我用0.15.0进行了测试,效果很好。您是否执行相同的确切代码
joaquin

是的,我只是将代码直接粘贴到一个新的控制台中。看来现在可以正常工作了!

1
在python> 3中,您不需要这样做,x = x.set_value(i, i**2)因为直接x.set_value()进行了更改x
jeongmin.cha

16
是的,不建议使用set_value()。使用x.at[i] = i**2x.iat[i] = i**2
Wolfgang Kuehn '18

39

TLDR:不要将项目逐个追加到一个序列中,最好通过有序集合进行扩展

我认为当前形式的问题有些棘手。并且接受的答案确实回答了问题。但是我使用熊猫的次数越多,我越了解将物品逐个追加到Series中是一个坏主意。我将尝试为熊猫初学者解释原因。

您可能会认为将数据附加到给定的Series可能会允许您重用某些资源,但实际上Series只是一个存储索引和值数组之间关系的容器。每个都是底层的numpy.array,索引是不可变的。当您向Series添加带有索引中缺少标签的项目时,将创建一个大小为n + 1的新索引,并创建一个具有相同大小的新values值数组。这意味着,当您逐项附加项时,您将在每个步骤上创建另外两个n + 1大小的数组。

顺便说一句,您不能按位置追加新项目(您将得到一个IndexError),并且索引中的标签不必唯一,也就是说,当您为标签分配值时,您可以将值分配给所有带有标签的现有项目,在这种情况下不会添加新行。这可能会导致细微的错误。

这个故事的寓意是,您不应该一个接一个地添加数据,而应该使用有序集合进行扩展。问题是您不能就地扩展Series。这就是为什么最好组织代码以便您无需通过引用来更新Series的特定实例的原因。

如果您自己创建标签并且标签不断增加,最简单的方法是将新项目添加到词典中,然后从词典中创建新的系列(对键进行排序),然后将系列附加到旧的系列中。如果键没有增加,则需要为新标签和新值创建两个单独的列表。

以下是一些代码示例:

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)

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

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)

也就是说,如果您要追加几个项目,将它们收集在字典中,创建一个系列,然后将其追加到旧项目并保存结果:

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

25

如果您有索引和值。然后,您可以将“序列”添加为:

obj = Series([4,7,-5,3])
obj.index=['a', 'b', 'c', 'd']

obj['e'] = 181

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


2
简短而直接的好答案。
Briford Wylie

1
这是最好的答案
boardtc

12

您可以使用append函数向其中添加另一个元素。仅在添加新元素之前,制作一系列新元素:

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

3
我相信append返回一个新系列(而不是在原地进行),所以您想要test = test.append(pd.Series(200, index=[101]))
A.Wan 2014年

1
@ A.Wan是的,应该更清楚一点。谢谢!
fixxxer

7

将以下形式添加到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

至于不推荐使用@joaqin的解决方案,因为该set_value方法将在以后的熊猫版本中删除,所以我要提到另一个选择,使用.at[]访问器将单个项目添加到熊猫系列中。

>>> 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

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

0

这是在不更改系列名称的情况下在一行中添加多个项目的另一种思路。但是,这可能没有其他答案有效。

>>> 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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.