Python 如果每列每行有多个值,如何在数据帧中的两列之间创建字典?
我有一个pandas数据框,其列的格式如下所示:Python 如果每列每行有多个值,如何在数据帧中的两列之间创建字典?,python,pandas,dataframe,dictionary,Python,Pandas,Dataframe,Dictionary,我有一个pandas数据框,其列的格式如下所示: test_df = pd.DataFrame( {'A': ['apples|oranges|bananas', 'apples|oranges', 'apples|kiwi'], 'B': ['store1|store2|store3', 'store1|store2', 'store1|store4']}) A B apples|oranges|bananas store1|store
test_df = pd.DataFrame(
{'A': ['apples|oranges|bananas', 'apples|oranges', 'apples|kiwi'],
'B': ['store1|store2|store3', 'store1|store2', 'store1|store4']})
A B
apples|oranges|bananas store1|store2|store3
apples|oranges store1|store2
apples|kiwi store1|store4
以“|”分隔的每列的索引都是有序的。除了dataframe中每行的当前项目顺序之外,没有关于哪个水果与哪个存储的键。我想为具有所需输出的每一行创建一个新列,其中包含一个字典:
A B C
apples|oranges|bananas store1|store2|store3 {store1:apples, store2:oranges, store3:bananas}
apples|oranges store1|store2 {store1:apples, store2:oranges}
apples|kiwi store1|store4 {store1:apples, store4:kiwi}
首先,我尝试将A列和B列转换为列表,并将它们转换为字典
test_df.A = test_df.A.str.split('|').tolist()
test_df.B = test_df.B.str.split('|').tolist()
我尝试了几种将列表转换为词典的不同方法:
test_df['C'] = dict(zip(test_df.A,test_df.B))
不工作并导致“TypeError:“dict”对象不可调用”错误
test_df.groupby('A')['B'].apply(list).to_dict()
不起作用并导致“Unhabable type:'list”错误,我认为这是因为“B”中的字典键有多个值
我能做些什么来解决这个问题呢?如果你真的需要维护这个组织,你可以通过(缓慢的)应用程序来解决,首先拆分字符串,压缩结果列表,然后编写命令:
test_df['C'] = test_df.apply(lambda r: dict(zip(r.B.split('|'), r.A.split('|'))), axis=1)
A B C
0 apples|oranges|bananas store1|store2|store3 {'store1': 'apples', 'store2': 'oranges', 'store3': 'bananas'}
1 apples|oranges store1|store2 {'store1': 'apples', 'store2': 'oranges'}
2 apples|kiwi store1|store4 {'store1': 'apples', 'store4': 'kiwi'}
因为字典必须有唯一的键,如果B
中的存储在同一行重复,请将dict
更改为tuple
,这样您就可以存储所有内容
但是,您可以使用
explode
获得类似的组织。由于这将以一种简单的方式存储所有数据,因此将来的操作将更加容易和高效。因为我们分解列,所以索引是重复的,并允许您知道它来自哪一行
test_df = pd.concat([test_df[col].str.split('|').explode() for col in test_df.columns], 1)
A B
0 apples store1
0 oranges store2
0 bananas store3
1 apples store1
1 oranges store2
2 apples store1
2 kiwi store4
如果您确实需要维护该组织,您可以(缓慢地)应用程序,首先拆分字符串,压缩生成的列表,然后编写命令:
test_df['C'] = test_df.apply(lambda r: dict(zip(r.B.split('|'), r.A.split('|'))), axis=1)
A B C
0 apples|oranges|bananas store1|store2|store3 {'store1': 'apples', 'store2': 'oranges', 'store3': 'bananas'}
1 apples|oranges store1|store2 {'store1': 'apples', 'store2': 'oranges'}
2 apples|kiwi store1|store4 {'store1': 'apples', 'store4': 'kiwi'}
因为字典必须有唯一的键,如果B
中的存储在同一行重复,请将dict
更改为tuple
,这样您就可以存储所有内容
但是,您可以使用
explode
获得类似的组织。由于这将以一种简单的方式存储所有数据,因此将来的操作将更加容易和高效。因为我们分解列,所以索引是重复的,并允许您知道它来自哪一行
test_df = pd.concat([test_df[col].str.split('|').explode() for col in test_df.columns], 1)
A B
0 apples store1
0 oranges store2
0 bananas store3
1 apples store1
1 oranges store2
2 apples store1
2 kiwi store4
我会认真重新考虑你的数据组织。数据帧最适合于平面数据,其中每个单元格都保存一个简单值。MutliIndex允许您存储更多层次化的数据,同时保留这个扁平的组织,并且仍然允许您从pandas的性能中获益。我将认真重新思考您的数据组织。数据帧最适合于平面数据,其中每个单元格都保存一个简单值。MutliIndex允许您存储更多层次化数据,同时保留这个扁平的组织,并且仍然允许您从pandas的性能中获益。感谢您的解决方案,我想我现在理解了explode对于存储这些数据的重要性。不幸的是,使用这两种方法,我仍然会遇到一些错误。第一个解决方案给我一个“TypeError:(“'dict'对象不可调用”,“在索引0处发生”)消息,explode方法给我一个“AttributeError:'Series'对象没有属性'explode'。有没有任何理由说明这可能不起作用?@Erika the second可能不起作用,因为你的熊猫版本太旧了。我想它是在0.24引入的,所以如果可以的话,它可能值得更新你的熊猫。第一种方法可能不起作用,因为您意外地将一个变量定义为
dict=
,所以您重写了内置的dict
类。您需要重新启动内核,并确保不命名变量dict
。感谢您的解决方案,我想我现在已经理解了explode对于存储这些数据的重要性。不幸的是,使用这两种方法,我仍然会遇到一些错误。第一个解决方案给我一个“TypeError:(“'dict'对象不可调用”,“在索引0处发生”)消息,explode方法给我一个“AttributeError:'Series'对象没有属性'explode'。有没有任何理由说明这可能不起作用?@Erika the second可能不起作用,因为你的熊猫版本太旧了。我想它是在0.24引入的,所以如果可以的话,它可能值得更新你的熊猫。第一种方法可能不起作用,因为您意外地将一个变量定义为dict=
,所以您重写了内置的dict
类。您需要重新启动内核并确保没有命名变量dict