Python pandas:逐行填充数据框
Posted
技术标签:
【中文标题】Python pandas:逐行填充数据框【英文标题】:Python pandas: fill a dataframe row by row 【发布时间】:2013-06-10 02:47:10 【问题描述】:向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
那也惨败了。
那么你是怎么做到的呢?
【问题讨论】:
请注意,逐行添加数据和大型数据集的效率非常低。相反,首先将数据加载到列表列表中,然后使用df = pd.DataFrame(data, columns=header)
在一行中构造 DataFrame 会快得多
为什么在 Lists 中创建数据集效率更高,并且看似将内存中的整个数据集复制为 DataFrame?这在内存使用方面听起来非常低效 - 对于非常庞大的数据集来说可能是一个问题。
@xApple,我想你遇到了同样的问题(好几天),我不明白 Columns 和 Index 之间的区别 - 我在考虑数组,这些可以基本上是 row/col 或反之亦然,没有区别。我完全同意你的观点,关于如何使用数据帧以及如何逐行生成 DF(从其他来源读取数据时很典型)的基本理论非常不清楚!
【参考方案1】:
df['y']
会设置一列
既然要设置一行,就用.loc
注意 .ix
在这里是等价的,你的失败是因为你试图分配一个字典
到行y
的每个元素可能不是您想要的;转换为系列告诉熊猫
您想要对齐输入(例如,您不必指定所有元素)
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
【讨论】:
我明白了。所以数据框的loc
属性定义了一个特殊的__setitem__
,它可以发挥我的作用。
你能一次性构造它吗(即使用列、索引和 y)?
那么如果我可以一次生成一行,我将如何优化构建数据框?
@xApple prob 最适合您构造一个 dicts 列表(或列表),然后只需传递给构造函数,效率会高得多
@amc 是的,你也可以df = pandas.DataFrame(columns=['a', 'b', 'c', 'd']); df.loc['y'] = [1, 5, 2, 3]
【参考方案2】:
我的方法是,但我不能保证这是最快的解决方案。
df = pd.DataFrame(columns=["firstname", "lastname"])
df = df.append(
"firstname": "John",
"lastname": "Johny"
, ignore_index=True)
【讨论】:
这对我来说非常有效,我喜欢你明确地append
数据到数据框的事实。
请注意,此答案需要每一行都附加列名。接受的答案相同。
如果您事先不知道行数,这也可以。
如果逐行构建但使用大型数据集,即使使用ignore_index=True
,这是您可以做的最好的事情,将数据加载到列表列表中然后构造使用 `df = pd.DataFrame(data, columns=header) 在一行中的 DataFrame。无论索引处理如何,pandas 在追加行时似乎都做了一些相当繁重的工作。
@Ben - 我没有测试过,但连接两个数据库应该快得多,正如你所展示的,而不是一次添加一行。但是,对于小型数据集,时间差异可能不会被肉眼注意到。【参考方案3】:
这是一个更简单的版本
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>']`
【讨论】:
只想问,这个CPU和内存效率高吗? 我怎么知道df的最后一行,所以我每次都追加到最后一行? 与append()
的其他两个选项(可能在每次循环迭代时复制整个数据库(当您重新分配给自己))以及创建两个相同数据结构的另一个常见选项(a List
然后是 DataFrame
) 相同的数据,这在内存使用方面似乎更“有效”,但速度可能完全是另一个问题。
也许你可以做df.loc[-1]
?
您可以将数据添加到 DataFrame 的末尾:df.loc[ len(df) ] = ["My", "new", "Data"]
【参考方案4】:
如果您的输入行是列表而不是字典,那么以下是一个简单的解决方案:
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']) 不起作用。形状不对。那怎么办?【参考方案5】:代码背后的逻辑非常简单直接
使用字典制作 1 行的 df
然后创建一个形状为 (1, 4) 的 df,它只包含 NaN 并且与字典键具有相同的列
然后将一个 nan df 与 dict df 连接,然后再连接另一个 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]
【讨论】:
以上是关于Python pandas:逐行填充数据框的主要内容,如果未能解决你的问题,请参考以下文章
Python、Pandas 和 for 循环:根据与列表值的匹配填充数据框行
使用 Python 用稀疏的 CSV 数据填充 Pandas 数据框