Python 熊猫: 逐行填充数据框

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

这就是我想做的。我有一个 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

现在,我有一个函数来迭代计算行的值。如何用字典或 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

但也惨败了。

你是怎么做到的?

280957 次浏览

df['y']将设置一个列

既然要设置一行,那么使用 .loc

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

In [6]: import pandas as pd


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


In [8]: df.loc['y'] = pd.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

这是一个更简单的版本

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>']`

更新: 因为 附录已被弃用

df = pd.DataFrame(columns=["firstname", "lastname"])


entry = pd.DataFrame.from_dict({
"firstname": ["John"],
"lastname":  ["Johny"]
})


df = pd.concat([df, entry], ignore_index=True)

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

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

代码背后的逻辑非常简单和直接

使用字典创建一个带有1行的 df

然后创建一个形状(1,4)的 df,它只包含 NaN,并且具有与字典键相同的列

然后连接一个 nan df 和 dictdf 然后再连接另一个 nan df

import pandas as pd
import numpy as np


raw_datav = {'a':1, 'b':5, 'c':2, 'd':3}


datav_df = pd.DataFrame(raw_datav, index=[0])


nan_df = pd.DataFrame([[np.nan]*4], columns=raw_datav.keys())


df = pd.concat([nan_df, datav_df, nan_df], ignore_index=True)


df.index = ["x", "y", "z"]


print(df)

给予

a    b    c    d
x  NaN  NaN  NaN  NaN
y  1.0  5.0  2.0  3.0
z  NaN  NaN  NaN  NaN


[Program finished]