Python 在单元格中使用列表对数据帧进行子集设置

Python 在单元格中使用列表对数据帧进行子集设置,python,pandas,dataframe,subset,Python,Pandas,Dataframe,Subset,假设我有以下数据帧 df = pd.DataFrame({'col1': ['one','one', 'one', 'one', 'two'], 'col2': ['two','two','four','four','two'], 'col3': [['alpha', 'beta'], ['alpha', 'beta'],

假设我有以下数据帧

df = pd.DataFrame({'col1': ['one','one', 'one', 'one', 'two'],
                   'col2': ['two','two','four','four','two'],
                   'col3': [['alpha', 'beta'],
                            ['alpha', 'beta'],
                            ['alpha', 'beta'],
                            ['alpha', 'beta'],
                            ['alpha', 'nodata', 'beta', 'gamma']]})
我知道我可以:

df[df['col2']=='four']
如何创建子集以使其与列表中的字符串匹配?在本例中,将col3中不包含“nodata”的行子集

df[~df['col3'].str.contains('nodata') 

似乎不起作用,而且我似乎无法正确访问列表中的“右”项。

如果将列的数据类型转换为字符串,则代码应该可以工作:

df[~df['col3'].astype(str).str.contains('nodata')]

与转换数据类型不同,您可以使用
apply
lambda
函数,这将更快一些

df[~df.col3.apply(lambda x: 'nodata' in x)]
在更大的数据集上测试它:

In [86]: df.shape
Out[86]: (5000, 3)   
我的解决方案:

In [88]: %timeit df[~df.col3.apply(lambda x: 'nodata' in x)]
         1000 loops, best of 3: 1.68 ms per loop
In [87]: %timeit df[~df['col3'].astype(str).str.contains('nodata')]
         100 loops, best of 3: 7.8 ms per loop
以前的解决方案:

In [88]: %timeit df[~df.col3.apply(lambda x: 'nodata' in x)]
         1000 loops, best of 3: 1.68 ms per loop
In [87]: %timeit df[~df['col3'].astype(str).str.contains('nodata')]
         100 loops, best of 3: 7.8 ms per loop

可以说,第一个答案可能更具可读性

您是要获取包含“nodata”的行还是所有不包含“nodata”的行?您说您想要得到那一行,但是您的示例代码在条件上是否定的,这意味着您想要的是不包含该行的行。同意。lambda非常有用。你们知道我可以在哪里钻研python lambda并一劳永逸地学习它们吗?我可能会先用它,然后用谷歌搜索一段时间。这里如何使用它的关键是它是一个应用于
df.col3
中每个单元格值的函数祝你好运!如果改用列表理解,速度会更快(并且可能会丢失lambda):
df[[['nodata'不在x中表示df.col3中的x]