Python pandas将列表插入单元格中
Python pandas将列表插入单元格中
我有一个列表'abc'和一个数据框'df':
abc = ['foo', 'bar'] df = A B 0 12 NaN 1 23 NaN
我想把列表插入到1B单元格,所以我想要这个结果:
A B 0 12 NaN 1 23 ['foo', 'bar']
我该如何做呢?
1) 如果我使用这个:
df.ix[1,'B'] = abc
我会得到以下错误信息:
ValueError: Must have equal len keys and value when setting with an iterable
因为它试图将列表(有两个元素)插入到行/列中,而不是单元格中。
2) 如果我使用这个:
df.ix[1,'B'] = [abc]
那么它会插入一个只有一个元素的列表,该元素是'abc'列表( [['foo', 'bar']]
)。
3) 如果我使用这个:
df.ix[1,'B'] = ', '.join(abc)
那么它会插入一个字符串:( foo, bar
),而不是列表。
4) 如果我使用这个:
df.ix[1,'B'] = [', '.join(abc)]
那么它会插入一个列表,但它只有一个元素( ['foo, bar']
),而不是我想要的两个元素( ['foo', 'bar']
)。
谢谢帮助!
编辑
我的新数据框和旧列表:
abc = ['foo', 'bar'] df2 = A B C 0 12 NaN 'bla' 1 23 NaN 'bla bla'
另一个数据框:
df3 = A B C D 0 12 NaN 'bla' ['item1', 'item2'] 1 23 NaN 'bla bla' [11, 12, 13]
我想把'abc'列表插入到df2.loc[1,'B']
和/或df3.loc[1,'B']
。
如果数据框只有整数值和/或NaN值和/或列表值的列,那么将列表插入到单元格中就可以完美地工作。如果数据框只有字符串值和/或NaN值和/或列表值的列,那么将列表插入到单元格中就可以完美地工作。但是如果数据框中既有整数和字符串值的列,又有其他列,则如果我使用这个:df2.loc[1,'B'] = abc
或df3.loc[1,'B'] = abc
,就会出现错误消息。
另一个数据框:
df4 = A B 0 'bla' NaN 1 'bla bla' NaN
这些插入操作完全正常: df.loc[1,'B'] = abc
或 df4.loc[1,'B'] = abc
。
Python pandas 中的 DataFrame 提供了一个方法 set_value() 来修改某个位置上的值。例如,df3.set_value(1, 'B', abc)
可以用来将变量 abc 插入到 DataFrame df3 的第 1 行、'B' 列的位置上。这个方法适用于任何 DataFrame。
但是需要注意的是,要注意目标列 'B' 的数据类型。例如,如果目标列是 float 类型,就不能直接插入一个列表。此时,可以使用 df['B'] = df['B'].astype(object)
将目标列的数据类型转换为 object 类型。
需要注意的是,以上方法在新版本的 pandas 中已经被标记为过时(deprecated)。有一个更新的方法可以替代上述方法。
Pandas版本大于等于0.21之后,set_value方法被弃用。现在可以使用DataFrame.at按标签设置值,使用DataFrame.iat按整数位置设置值。
如果想要将“B”列的第二行的值设置为新的列表,可以使用DataFrame.at:
df.at[1, 'B'] = ['m', 'n']
也可以使用DataFrame.iat按整数位置设置值:
df.iat[1, df.columns.get_loc('B')] = ['m', 'n']
如果出现“ValueError: setting an array element with a sequence”错误,可能是因为对象的dtype是float64,而列表是object类型,导致类型不匹配。在这种情况下,需要先将列转换为object类型:
df['B'] = df['B'].astype(object)
然后再设置值即可。
另外,通过DataFrame.loc也可以实现类似的效果,如果传入嵌套列表:
df.loc[1, 'B'] = [['m'], ['n'], ['o'], ['p']]
通过DataFrame.loc的方法可以实现,但是并不常见。更多关于这种方法的解释可以参考这里。
,Pandas版本大于等于0.21后,使用DataFrame.at和DataFrame.iat可以设置单元格的值,如果出现类型不匹配错误,可以先将列转换为object类型。
在版本0.21.0之后,set_value
已被弃用,现在应该使用at
。它可以将一个列表插入到单元格中,而不会像loc
一样引发ValueError
。我认为这是因为at
始终只引用一个单值,而loc
可以引用值、行和列。
你还需要确保你要插入的列具有dtype=object
。例如:
>>> df = pd.DataFrame(data={'A': [1, 2, 3], 'B': [1,2,3]}) >>> df.dtypes A int64 B int64 dtype: object >>> df.at[1, 'B'] = [1, 2, 3] ValueError: setting an array element with a sequence >>> df['B'] = df['B'].astype('object') >>> df.at[1, 'B'] = [1, 2, 3] >>> df A B 0 1 1 1 2 [1, 2, 3] 2 3 3
非常有帮助,但是当尝试将列表作为数据帧的新行值时,怎么办呢?我想要在发现数据时迭代地添加行。过去我使用.loc
是因为它可以添加新行,但是它不能存储一个列表。据我所知,.at
可以存储一个列表,但不能添加新行。