Python Pandas:逐行填充数据框


133

pandas.DataFrame对象添加一行的简单任务似乎很难完成。有3个与此相关的stackoverflow问题,没有一个给出有效的答案。

这就是我想要做的。我有一个DataFrame,我已经知道它的形状以及行和列的名称。

>>> df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])
>>> df
     a    b    c    d
x  NaN  NaN  NaN  NaN
y  NaN  NaN  NaN  NaN
z  NaN  NaN  NaN  NaN

现在,我有一个函数来迭代计算行的值。如何用字典或a填充行之一pandas.Series?这是各种失败的尝试:

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df['y'] = y
AssertionError: Length of values does not match length of index

显然,它试图添加一列而不是一行。

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.join(y)
AttributeError: 'builtin_function_or_method' object has no attribute 'is_unique'

错误消息非常少。

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.set_value(index='y', value=y)
TypeError: set_value() takes exactly 4 arguments (3 given)

显然,这仅用于设置数据框中的各个值。

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.append(y)
Exception: Can only append a Series if ignore_index=True

好吧,我不想忽略索引,否则结果如下:

>>> df.append(y, ignore_index=True)
     a    b    c    d
0  NaN  NaN  NaN  NaN
1  NaN  NaN  NaN  NaN
2  NaN  NaN  NaN  NaN
3    1    5    2    3

它确实使列名与值对齐,但是丢失了行标签。

>>> y = {'a':1, 'b':5, 'c':2, 'd':3} 
>>> df.ix['y'] = y
>>> df
                                  a                                 b  \
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

                                  c                                 d
x                               NaN                               NaN
y  {'a': 1, 'c': 2, 'b': 5, 'd': 3}  {'a': 1, 'c': 2, 'b': 5, 'd': 3}
z                               NaN                               NaN

那也失败了。

你是怎么做到的 ?

Answers:


92

df['y'] 将设置一列

由于您要设置行,请使用 .loc

请注意,这.ix等效于您,您的失败了,因为您试图为该行的每个元素分配一个字典,y可能不是您想要的。转换为Series会告诉熊猫您要对齐输入(例如,您不必指定所有元素)

In [7]: df = pandas.DataFrame(columns=['a','b','c','d'], index=['x','y','z'])

In [8]: df.loc['y'] = pandas.Series({'a':1, 'b':5, 'c':2, 'd':3})

In [9]: df
Out[9]: 
     a    b    c    d
x  NaN  NaN  NaN  NaN
y    1    5    2    3
z  NaN  NaN  NaN  NaN

我懂了。因此,loc数据框的属性定义了一种特殊的功能__setitem__,它可以实现我想像的魔术。
xApple

您可以一次构建它(即使用列,索引和y)吗?
安迪·海登

5
因此,如果我一次可以生成一行,那么我将如何优化构造数据帧?
xApple

期待某种变体df = pd.DataFrame({'y': pd.Series(y)}, columns=['a','b','c','d'], index=['x','y','z'])工作吗?
安迪·海登

@xApple最有可能为您构造字典(或列表)列表,然后将其传递给构造函数,效率会更高
Jeff

71

我的方法是,但是我不能保证这是最快的解决方案。

df = pd.DataFrame(columns=["firstname", "lastname"])
df = df.append({
     "firstname": "John",
     "lastname":  "Johny"
      }, ignore_index=True)

4
这对我来说非常出色,我喜欢您append将数据显式添加到数据框的事实。
乔尼·布鲁克斯

1
请注意,此答案需要在每一行后附加列名。相同的答案。
pashute

如果您事先不知道行数,也可以使用。
艾琳

34

这是一个简单的版本

import pandas as pd
df = pd.DataFrame(columns=('col1', 'col2', 'col3'))
for i in range(5):
   df.loc[i] = ['<some value for first>','<some value for second>','<some value for third>']`

4
只想问一下,这种CPU和内存效率高吗?
czxttkl

1
我怎么知道df的最后一行,所以每次都附加到最后一行?
pashute

25

如果您的输入行是列表而不是字典,那么以下是一个简单的解决方案:

import pandas as pd
list_of_lists = []
list_of_lists.append([1,2,3])
list_of_lists.append([4,5,6])

pd.DataFrame(list_of_lists, columns=['A', 'B', 'C'])
#    A  B  C
# 0  1  2  3
# 1  4  5  6

但是,如果我有多重索引该怎么办?df1 = pd.DataFrame(list_of_lists,columns ['A','B','C'],index = ['A','B'])不起作用。错误的形状。又怎样?
pashute
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.