Pandas 如何从数据框和列中的列表中弹出行
我有一个数据框,其中一列是列表。该列表是标签的通用列表Pandas 如何从数据框和列中的列表中弹出行,pandas,list,dataframe,Pandas,List,Dataframe,我有一个数据框,其中一列是列表。该列表是标签的通用列表 df = pd.DataFrame({'label': ['cell_1', 'cell_1', 'cell_1', 'cell_1', 'cell_2', 'cell_2', 'cell_2'], 'index': [1, 2, 5, 6, 1, 18, 5], 'item': [121, 989, 222, 333, 878, 777, 878],
df = pd.DataFrame({'label': ['cell_1', 'cell_1', 'cell_1', 'cell_1', 'cell_2', 'cell_2', 'cell_2'],
'index': [1, 2, 5, 6, 1, 18, 5],
'item': [121, 989, 222, 333, 878, 777, 878],
'list': [[121, 454, 989], [121, 454, 989], [121, 454, 989], [121, 454, 989], [111, 777, 999], [111, 777, 999], [111, 777, 999]]})
label index item list
0 cell_1 1 121 [121, 454, 989]
1 cell_1 2 989 [121, 454, 989]
2 cell_1 5 222 [121, 454, 989]
3 cell_1 6 333 [121, 454, 989]
4 cell_2 1 878 [111, 777, 999]
5 cell_2 18 777 [111, 777, 999]
6 cell_2 5 878 [111, 777, 999]
我想检查item列中的值是否在列表中。如果是,我想将行弹出到它自己的数据帧中:
popped_df
label index item
0 cell_1 1 121
1 cell_1 2 989
2 cell_2 18 777
df
label index item list
0 cell_1 5 222 [454]
1 cell_1 6 333 [454]
2 cell_2 1 878 [111, 999]
3 cell_2 5 878 [111, 999]
并从剩余数据框的列表中删除项值:
popped_df
label index item
0 cell_1 1 121
1 cell_1 2 989
2 cell_2 18 777
df
label index item list
0 cell_1 5 222 [454]
1 cell_1 6 333 [454]
2 cell_2 1 878 [111, 999]
3 cell_2 5 878 [111, 999]
我尝试了很多东西,但都遇到了大问题。我认为解决方案可能是将数据放在嵌套字典中,以label作为键,每个索引作为一个值并进行迭代。我宁愿不要从数据帧到字典再到字典,即使这意味着性能很慢
提前谢谢你
如果希望将列表保存在列表中而不是分解数据帧,则可以使用列表理解来执行此操作。由于要比较多个列,请在数据帧上使用.applylambda x:,其中x是数据帧,并传递列和轴=1,以在默认轴=0上按列移动。使用explode时性能可能会更好,但我将测试此方法与explode方法的比较。
要去除初始数据帧的值,请使用非常类似的列表理解技术
我建议您分解列表,然后执行基本布尔索引器: df.分解“列表” .loc[lambda df:~df['list'].isindf['item']&~df['item'].isindf['list']] .pivot_tableindex=['label'、'index'、'item'],values='list',aggfunc=list .reset_索引 这给了我:
label index item list
0 cell_1 5 222 [454]
1 cell_1 6 333 [454]
2 cell_2 1 878 [111, 999]
3 cell_2 5 878 [111, 999]
但我建议您不要将值放在列表中,忽略对pivot_表的调用
您可以翻转逻辑以获取其他数据帧:
popped_df
label index item
0 cell_1 1 121
1 cell_1 2 989
2 cell_2 18 777
df
label index item list
0 cell_1 5 222 [454]
1 cell_1 6 333 [454]
2 cell_2 1 878 [111, 999]
3 cell_2 5 878 [111, 999]
df.分解“列表”
.loc[lambda df:df['list'].isindf['item']&df['item'].isindf['list']]
.dropcolumns=['list']
.drop_duplicateSubset=['label','index']
.to_字符串
即:
label index item
0 cell_1 1 121
1 cell_1 2 989
5 cell_2 18 777
请注意,一般来说,所谓的整洁数据更容易处理:
df.explode'list'.reset\u indexdrop=True
Paul和David的答案非常有用,但不幸的是,当我将它们应用于我的完整数据集时,我发现他们的解决方案从整个列表列中删除了项,而不仅仅是标签的公共列表。例如,如果我添加的列表项同时出现在单元格_1和单元格_2列表中:
df = pd.DataFrame({'label': ['cell_1', 'cell_1', 'cell_1', 'cell_1', 'cell_2', 'cell_2', 'cell_2'],
'index': [1, 2, 5, 6, 1, 18, 5],
'item': [121, 989, 222, 333, 878, 777, 878],
'list': [[121, 454, 989], [121, 454, 989], [121, 454, 989], [121, 454, 989], [121, 777, 999], [121, 777, 999], [121, 777, 999]]})
label index item list
0 cell_1 1 121 [121, 454, 989]
1 cell_1 2 989 [121, 454, 989]
2 cell_1 5 222 [121, 454, 989]
3 cell_1 6 333 [121, 454, 989]
4 cell_2 1 878 [121, 777, 999]
5 cell_2 18 777 [121, 777, 999]
6 cell_2 5 878 [121, 777, 999]
对于这两种解决方案,单元格_2的列表已被删除,尽管我只想将其从单元格_1共有的列表单元格中删除:
s = df.apply(lambda x: any([True for y in x['list'] if x['item'] == y ]), axis=1)
df1 = df[s].drop('list', axis=1)
df['list'] = df.apply(lambda x: [y for y in x['list'] if y not in df1['item'].unique()], axis=1)
df = df[~s]
df1, df
( label index item
0 cell_1 1 121
1 cell_1 2 989
5 cell_2 18 777,
label index item list
2 cell_1 5 222 [454]
3 cell_1 6 333 [454]
4 cell_2 1 878 [999]
6 cell_2 5 878 [999])
我最后做的是爆炸数据,使其整洁:
df.explode('list').reset_index(drop=True)
df
label index item list
0 cell_1 1 121 121
1 cell_1 1 121 454
2 cell_1 1 121 989
3 cell_1 2 989 121
4 cell_1 2 989 454
5 cell_1 2 989 989
6 cell_1 5 222 121
7 cell_1 5 222 454
8 cell_1 5 222 989
9 cell_1 6 333 121
10 cell_1 6 333 454
11 cell_1 6 333 989
12 cell_2 1 878 121
13 cell_2 1 878 777
14 cell_2 1 878 999
15 cell_2 18 777 121
16 cell_2 18 777 777
17 cell_2 18 777 999
18 cell_2 5 878 121
19 cell_2 5 878 777
20 cell_2 5 878 999
然后添加额外的列:
df['lookup1'] = df['label'] + "-" + df['item'].astype(str)
df.loc[(df['item'] == df['list']), 'lookup2'] = df['label'] + "-" + df['item'].astype(str)
df["selector"] = df['lookup1'].isin(df["lookup2"])
df
label index item list lookup1 lookup2 selector
0 cell_1 1 121 121 cell_1-121 cell_1-121 True
1 cell_1 1 121 454 cell_1-121 NaN True
2 cell_1 1 121 989 cell_1-121 NaN True
3 cell_1 2 989 121 cell_1-989 NaN True
4 cell_1 2 989 454 cell_1-989 NaN True
5 cell_1 2 989 989 cell_1-989 cell_1-989 True
6 cell_1 5 222 121 cell_1-222 NaN False
7 cell_1 5 222 454 cell_1-222 NaN False
8 cell_1 5 222 989 cell_1-222 NaN False
9 cell_1 6 333 121 cell_1-333 NaN False
10 cell_1 6 333 454 cell_1-333 NaN False
11 cell_1 6 333 989 cell_1-333 NaN False
12 cell_2 1 878 121 cell_2-878 NaN False
13 cell_2 1 878 777 cell_2-878 NaN False
14 cell_2 1 878 999 cell_2-878 NaN False
15 cell_2 18 777 121 cell_2-777 NaN True
16 cell_2 18 777 777 cell_2-777 cell_2-777 True
17 cell_2 18 777 999 cell_2-777 NaN True
18 cell_2 5 878 121 cell_2-878 NaN False
19 cell_2 5 878 777 cell_2-878 NaN False
20 cell_2 5 878 999 cell_2-878 NaN False
在这一点上,我可以对选择器列进行操作。当然有更优雅的方法可以做到这一点吗?是否需要保留列表?这类事情可能会更简单,而且性能更好,因为列表的值都在它们自己的列中。不必保留在列表中,它位于列表中的优点是列表的长度是可变的。第一次,我对列表数据做了一个数据透视图,其中包含了列表0、列表1、列表2等列,我将这些列合并到了数据透视图中。我看到了如何使用一组公式,比如:df.loc[df['item']==df['list\u item0'],'in\u list'=df['item']df.loc[df['item']==df['list\u item1'],'in\u list'=df['item'],这是我将使用的。
df['lookup1'] = df['label'] + "-" + df['item'].astype(str)
df.loc[(df['item'] == df['list']), 'lookup2'] = df['label'] + "-" + df['item'].astype(str)
df["selector"] = df['lookup1'].isin(df["lookup2"])
df
label index item list lookup1 lookup2 selector
0 cell_1 1 121 121 cell_1-121 cell_1-121 True
1 cell_1 1 121 454 cell_1-121 NaN True
2 cell_1 1 121 989 cell_1-121 NaN True
3 cell_1 2 989 121 cell_1-989 NaN True
4 cell_1 2 989 454 cell_1-989 NaN True
5 cell_1 2 989 989 cell_1-989 cell_1-989 True
6 cell_1 5 222 121 cell_1-222 NaN False
7 cell_1 5 222 454 cell_1-222 NaN False
8 cell_1 5 222 989 cell_1-222 NaN False
9 cell_1 6 333 121 cell_1-333 NaN False
10 cell_1 6 333 454 cell_1-333 NaN False
11 cell_1 6 333 989 cell_1-333 NaN False
12 cell_2 1 878 121 cell_2-878 NaN False
13 cell_2 1 878 777 cell_2-878 NaN False
14 cell_2 1 878 999 cell_2-878 NaN False
15 cell_2 18 777 121 cell_2-777 NaN True
16 cell_2 18 777 777 cell_2-777 cell_2-777 True
17 cell_2 18 777 999 cell_2-777 NaN True
18 cell_2 5 878 121 cell_2-878 NaN False
19 cell_2 5 878 777 cell_2-878 NaN False
20 cell_2 5 878 999 cell_2-878 NaN False