我正在尝试过滤一些列是列表的数据框。我想过滤掉不通过条件的元素。
例如:
import pandas as pd
df = pd.DataFrame({'col1':[10,20], 'col2': [[1,2,3],[3,4,5]], 'col3': [[False,False,True],[True,True,False]],'col4':[True,False]})
col1 col2 col3 col4
0 10 [1, 2, 3] [False, False, True] True
1 20 [3, 4, 5] [True, True, False] False
应用过滤器
df_filtered = df.query("col2>2 & col3==True")
我期望的输出
感谢您的帮助!
答案 0 :(得分:4)
试试:
df[['col2','col3']] = (pd.DataFrame({'col2': df['col2'].explode(),
'col3': df['col3'].explode()})
.query('col2>2 & col3==True')
.groupby(level=0).agg(list)
)
输出:
打印(df)
col1 col2 col3 col4
0 10 [3] [True] True
1 20 [3, 4] [True, True] False
答案 1 :(得分:2)
如果内存是主要约束,您可以使用 numpy
和迭代方法。
这会就地修改数据帧,而无需在此过程中创建大型临时数据结构:
import pandas as pd
import numpy as np
df = pd.DataFrame({'col1':[10,20], 'col2': [[1,2,3],[3,4,5]], 'col3': [[False,False,True],[True,True,False]]})
for idx, row in df.iterrows():
a1=np.array(row['col2'])
a2=np.array(row['col3'])
df.at[idx,'col2']=a1[(a1>2) & a2]
df.at[idx,'col3']=a2[a2]
>>> df
col1 col2 col3
0 10 [3] [True]
1 20 [3, 4] [True, True]
答案 2 :(得分:1)
由于列表在行中的大小相同,您可以像这样使用数组和掩码
arr2 = np.array(df['col2'].tolist())
arr3 = np.array(df['col3'].tolist())
df[['col2','col3']] = [[c2[b],c3[b]] for c2,c3,b in zip(arr2,arr3,(arr2>=2) & arr3)]
print(df)
col1 col2 col3 col4
0 10 [3] [True] True
1 20 [3, 4] [True, True] False
答案 3 :(得分:0)
另一种循环方式,但可能更慢:
for index, row in df.iterrows():
j=0
for i in df.at[index, 'col3']:
if i==False:
df.at[index, 'col2'].remove(df.at[index, 'col2'][j])
else:
j=j+1
df.at[index, 'col3']=list(filter(None, df.at[index, 'col3']))