在我的数据框中,我有一个包含项目列表的列。我想只选择那些包含所有或几个项目的行。至少匹配一个列表会很棒。
import pandas as pd
df = pd.DataFrame([[2,[2,3,8]]], columns=['a','b'])
df
我尝试了以下内容:
df[df['b'] == [2,3,8]]
df[[2,3,8] in df['b']] # and etc.
我觉得被蒙住眼睛......
到FooBar:
我正在进行科学领域分析。该列表包含不同科学领域的代码。行代表案例,当这些科学领域是共同的时候。我可以将列表成员保留在不同的列中,但问题是coocuring字段的数量正在发生变化。因此我认为将列表保存在单元格中是可以的。
答案 0 :(得分:2)
我认为你可以做到以下几点:
idx = []
S = [2,3,8]
for i, line in df.iterrows():
if set(S).issubset(line['b']):
idx.append(i)
现在,您只能选择您感兴趣的行:
df_subset = df.ix[idx]
答案 1 :(得分:1)
比较元组没有问题
import pandas as pd
data = [
[1, (2,3,8)],
[2, (12,13,18)],
[3, (2,3,8)],
[4, (1,2,3,8,10)],
[5, (8,3,2)],
]
#----------------------------------------------
df_tuple = pd.DataFrame( data, columns=['a','b'])
print '\n DataFrame with tuples \n'
print df_tuple
print '\n tuple == : \n'
print df_tuple['b'] == (2,3,8)
print df_tuple[ df_tuple['b'] == (2,3,8) ]
print '\n tuple eq() : \n'
print df_tuple['b'].eq((2,3,8))
print df_tuple[ df_tuple['b'].eq((2,3,8)) ]
#----------------------------------------------
结果
DataFrame with tuples
a b
0 1 (2, 3, 8)
1 2 (12, 13, 18)
2 3 (2, 3, 8)
3 4 (1, 2, 3, 8, 10)
4 5 (8, 3, 2)
tuple == :
0 True
1 False
2 True
3 False
4 False
Name: b, dtype: bool
a b
0 1 (2, 3, 8)
2 3 (2, 3, 8)
tuple eq() :
0 True
1 False
2 True
3 False
4 False
Name: b, dtype: bool
a b
0 1 (2, 3, 8)
2 3 (2, 3, 8)
但是比较列表存在问题,我不知道为什么。
但是您需要包含列表[2,3,8]
中所有或多个项目的行,因此我会将apply()
与自己的函数一起使用。
import pandas as pd
#----------------------------------------------
data = [
[1, [2,3,8]],
[2, [12,13,18]],
[3, [2,3,8]],
[4, [1,2,3,8,10]],
[5, [8,3,2]],
]
#----------------------------------------------
df_list = pd.DataFrame( data, columns=['a','b'])
print '\n DataFrame with lists \n'
print df_list
print '\n test: \n'
# test if any element from data list is in [2,3,8]
def test(data):
return any( x in [2,3,8] for x in data )
print df_list['b'].apply(test)
print df_list[ df_list['b'].apply(test) ]
#----------------------------------------------
结果
DataFrame with lists
a b
0 1 [2, 3, 8]
1 2 [12, 13, 18]
2 3 [2, 3, 8]
3 4 [1, 2, 3, 8, 10]
4 5 [8, 3, 2]
test:
0 True
1 False
2 True
3 True
4 True
Name: b, dtype: bool
a b
0 1 [2, 3, 8]
2 3 [2, 3, 8]
3 4 [1, 2, 3, 8, 10]
4 5 [8, 3, 2]
更有用的版本 - 第二个参数:
test_any
如果 数据列表中的任何元素位于预期列表
True
def test_any(data, expected):
return any( x in expected for x in data )
print df_list['b'].apply(lambda x:test_any(x,[2,3,8]) )
print df_list[ df_list['b'].apply(lambda x:test_any(x,[2,3,8]) ) ]
如果数据列表中的所有元素都在预期列表,则 test_all
返回True
def test_all(data, expected):
return all( x in expected for x in data )
print df_list['b'].apply(lambda x:test_all(x,[2,3,8]) )
print df_list[ df_list['b'].apply(lambda x:test_all(x,[2,3,8]) ) ]
您可以交换'x'和[2,3,8]
获取True
print df_list[ df_list['b'].apply(lambda x:test_any_2([2,3,8], x) ) ]
如果预期列表中所有元素位于数据列表,则获取True
print df_list[ df_list['b'].apply(lambda x:test_all_2([2,3,8], x) ) ]
答案 2 :(得分:1)
好吧,我执行以下操作以使您的数据帧更好地使用#34;格式。我允许任何数量的"科学属性",如你所说,并将其称为"其他"。
D = df
df = pd.concat([D['a'], pd.DataFrame(D['b'].tolist(), index=D.index)], axis=1, keys=['standard', 'additional'])
In[103]: df
Out[103]:
standard additional
a 0 1 2
0 2 2 3 8
现在我们只搜索"其他"你给我们的钥匙的一部分:
In[133]: any(df['additional'] == 3, axis=1) & any(df['additional'] == 8, axis=1)
Out[133]: array([ True], dtype=bool)
现在我只是破解了第二条假行,检查我是否真的"没有选择"那些不符合标准的人:
df2 = df.append(df)
df2.iloc[1] += 1
any(df2['additional'] == 3, axis=1) & any(df2['additional'] == 8, axis=1)
Out[132]: array([ True, False], dtype=bool)
确认:
我从HYRY here了解到concat()
的可爱利用率。