如何将熊猫列的值设置为列表
Posted
技术标签:
【中文标题】如何将熊猫列的值设置为列表【英文标题】:How to set the value of a pandas column as list 【发布时间】:2019-03-04 06:23:38 【问题描述】:我想将 pandas 列的值设置为字符串列表。但是,我这样做的努力没有成功,因为 pandas 将列值作为可迭代对象,我得到:ValueError: Must have equal len keys and value when setting with an iterable
。
这是一个 MWE
>> df = pd.DataFrame('col1': [1, 2, 3], 'col2': [4, 5, 6])
>> df
col1 col2
0 1 4
1 2 5
2 3 6
>> df['new_col'] = None
>> df.loc[df.col1 == 1, 'new_col'] = ['a', 'b']
ValueError: Must have equal len keys and value when setting with an iterable
我尝试使用df.new_col = df.new_col.astype(list)
将dtype
设置为list
,但这也不起作用。
我想知道这里的正确方法是什么。
编辑
此处提供的答案:Python pandas insert list into a cell 使用 at
对我也不起作用。
【问题讨论】:
Python pandas insert list into a cell的可能重复df.at[1, 'new_col'] = ['a', 'b']
为什么不添加 2 个新列而不是使用一个系列来保存列表?
【参考方案1】:
同样使用np.where:
df['new_col'] = np.where(df.col1 == 1, pd.Series([['a', 'b']]) , np.nan)
【讨论】:
【参考方案2】:不要这样做。
Pandas 从来没有被设计为按系列/列保存列表。您可以制定昂贵的解决方法,但不建议这样做。
不建议将列表保存在系列中的主要原因是您失去了使用保存在连续内存块中的 NumPy 数组的向量化功能。你的系列将是object
dtype,它代表一个指针序列,很像list
。您将失去内存和性能方面的好处,以及访问优化的 Pandas 方法。
另请参阅What are the advantages of NumPy over regular Python lists? 支持 Pandas 的论点与支持 NumPy 的论点相同。
也就是说,既然你要违背 Pandas 的目的和设计,那么有很多人面临同样的问题并提出了类似的问题:
Python pandas insert list into a cell pandas: how to store a list in a dataframe? Answer on this question【讨论】:
非常感谢您的回答。现在,我将不得不经历一个公会缠身的编码会议或重组整个事情。艰难的选择! 附带说明,如果必须在一列下存储任意长的值序列,推荐的方法是什么? @Unni,Pandas 可能不是适合你的结构。 Pandas 这个名字来源于panel data。因此,它专为存储在 数组 中的结构化数据而设计。该数组中的每一行都有索引,不能任意长。list
,可能结合dict
可能更合适。
如果你的单元格值是向量/张量怎么办?
@Ark-kun,如果您的向量长度相同,请使用数据框。否则,请使用其他东西,例如字典。【参考方案3】:
不容易,一种可能的解决方案是创建助手Series
:
df.loc[df.col1 == 1, 'new_col'] = pd.Series([['a', 'b']] * len(df))
print (df)
col1 col2 new_col
0 1 4 [a, b]
1 2 5 NaN
2 3 6 NaN
如果需要将缺失值也设置为空列表,另一种解决方案是使用列表理解:
#df['new_col'] = [['a', 'b'] if x == 1 else np.nan for x in df['col1']]
df['new_col'] = [['a', 'b'] if x == 1 else [] for x in df['col1']]
print (df)
col1 col2 new_col
0 1 4 [a, b]
1 2 5 []
2 3 6 []
但是你失去了使用 NumPy 数组保存在连续内存块中的向量化功能。
【讨论】:
非常感谢。这样可行!我会选择第一个并将其余的设置为NaN
或None
。如果我知道列表的长度一直受两个约束,我可能应该考虑两个单独的列。您是否认为像这样一次更新每一列会因为额外的内存提取而在大数据上变慢?【参考方案4】:
你可以试试下面的代码:
list1=[1,2,3]
list2=[4,5,6]
col=[str(“,”.join(map(str, list1))), str(“,”.join(map(str, list2)))]
df=pd.DataFrame(np.random.randint(low=0, high=0, size(5,2)), columns=col)
print(df)
希望这是预期的输出:
【讨论】:
这会将值存储为string
而不是list
。以上是关于如何将熊猫列的值设置为列表的主要内容,如果未能解决你的问题,请参考以下文章