pandas - python - 使用元素作为列表切割Dataframe

我的数据框有列表作为元素,我想有更有效的方法来检查一些条件。

我的数据框像这样


col_a col_b


0 100 [1, 2, 3]


1 200 [2, 1]


2 300 [3]



我只想得到B列中有1的行

我尝试过幼稚的方式temp_list =list()。


for i in range(len(df1.index)): 


 if 1 in df1.iloc[i,1]:


 temp_list.append(df1.iloc[i,0])



像这样的大型数据帧需要很多时间。 我怎样才能使这样的数据帧的搜索更有效呢

时间:


df[df.col_b.apply(lambda x: 1 in x)]



结果:


col_a col_b


0 100 [1, 2, 3]


1 200 [2, 1]



boolean indexing与列表推导一起使用将loc用于seelct列col_a


a = df1.loc[[1 in x for x in df1['col_b']], 'col_a'].tolist()


print (a)


[100, 200]



如果需要第一列:


a = df1.iloc[[1 in x for x in df1['col_b']], 0].tolist()


print (a)


[100, 200]



如果需要所有行:


df2 = df1[[1 in x for x in df1['col_b']]]


print (df2)


 col_a col_b


0 100 [1, 2, 3]


1 200 [2, 1]



setisdisjoint的另一个解决方案:


df2 = df1[~df1['col_b'].map(set({1}).isdisjoint)]


print (df2)


 col_a col_b


0 100 [1, 2, 3]


1 200 [2, 1]



你可以通过列表推导来检查给定列表中是否存在1,并且使用结果来执行boolean indexing on dataframe :


df.loc[[1 in i for i in df.col_B ],:]



 col_a col_B


0 100 [1, 2, 3]


1 200 [2, 1]



下面是使用sets的另一种方法:


df[df.col_B.ne(df.col_B.map(set).sub({1}).map(list))]



 col_a col_B


0 100 [1, 2, 3]


1 200 [2, 1]



我尝试了这种方法:


df['col_b'] = df.apply(lambda x: eval(x['col_b']), axis = 1) 


s=df['col_b']


d = pd.get_dummies(s.apply(pd.Series).stack()).sum(level=0)


df = pd.concat([df, d], axis=1); 


print(df)


print('...')


print(df[1.0])



在最后(列名称为1.0的列)中给出了这样的索引:


 id col_a col_b 1.0 2.0 3.0


0 1 100 (1, 2, 3) 1 1 1


1 2 200 (1, 2) 1 1 0


2 3 300 3 0 0 1


...


0 1


1 1


2 0


Name: 1.0, dtype: uint8



要打印结果:


df.loc[df[1.0]==1, ['id', 'col_a', 'col_b']]



...