过滤掉包含特定字符串的数据框行

3
我有一个庞大的数据框。数据框中有一个名为patient.drug的列。该列包含字典列表作为其元素。 我想要过滤掉所有在patient.drug列中包含'NIFEDIPINE'一词的行。
数据框非常庞大。这是一个样本。
                                                         patient.drug
0                       [{'drugcharacterization': '1', 'medicinalproduct': 'PANDOL'}]
1                       [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}]      
2                       [{'drugcharacterization': '3', 'medicinalproduct': 'SIMVASTATIN'}]
3                       [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}]      

到目前为止,我已经尝试过。
df[df['patient.drug'].str.contains('NIFEDIPINE')]

但是它给我一个错误。
 raise KeyError(f"None of [{key}] are in the [{axis_name}]")

KeyError: "None of [Float64Index([nan, nan, nan, nan, nan, nan, nan, nan, nan, nan,\n              ...\n              nan, nan, nan, nan, nan, nan, nan, nan, nan, nan],\n             dtype='float64', length=12000)] are in the [columns]"

我还尝试过使用in运算符和迭代行。
lst=[]
for i in range(len(df)):
    if 'NIFEDIPINE' in df.loc[i, "patirnt.drug"]:
        lst.append(i)
print(lst)

这也导致了一个错误。我应该怎么做才能弄对呢?

尝试 if i in df.loc: - Arkodeep Ray
1
看起来你的 patient.drug 列中有很多 NaN。请尝试使用 df[df["patient.drug"].str.contains("NIFEDIPINE", na=False)],它会将 NaN 替换为 False,以便在返回值中使用作为掩码。希望这样能够安全地使用。 - Mustafa Aydın
你能否包含你的数据框的一个小样本?这会让你的问题和期望的输出更清晰明了。 - rahlf23
@user16309118,现在它对你有效吗? - Karn Kumar
@KarnKumar 是的,它成功了。非常感谢你。 - user16309118
显示剩余5条评论
4个回答

1
假设你有这样的列布局:
搜索字符串“NIFEDIPINE”在第2个和第4个条目中找到:
data = {'patient.drug': 
     [[{'drugcharacterization': '1', 'medicinalproduct': 'PANDOL'}],
      [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}],
      [{'drugcharacterization': '3', 'medicinalproduct': 'SIMVASTATIN'}],
      [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}],
     ]
}
df = pd.DataFrame(data)

                                                         patient.drug
0       [{'drugcharacterization': '1', 'medicinalproduct': 'PANDOL'}]
1   [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}]      <=== keyword here
2  [{'drugcharacterization': '3', 'medicinalproduct': 'SIMVASTATIN'}]
3   [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}]      <=== keyword here

(从您以前的问题中挖掘出的布局)

解决方案:

【已更新以支持1)在列表中使用多个字典和2)部分字符串匹配】。

使用:.loc + .explode() + .apply()

keyword = 'NIFEDIPINE'
df.loc[df['patient.drug'].explode().apply(lambda d: keyword in ' '.join(d.values())).any(level=0)]

结果:

成功提取并显示包含关键词“NIFEDIPINE”的行:

                                                        patient.drug
1  [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}]
3  [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}]

我尝试了这个。它报错了:ValueError: 无法从重复的轴重新索引 - user16309118
1
@KarnKumar 是的,我已经在问题中添加了一个示例。 - user16309118
@user16309118 是否有一些条目可以在列表中包含多个字典? - SeaBean
@SeaBean 是的,有些词条有多个字典。 - user16309118
@SeaBean,我刚试了一下,它可以工作。但是它只给了我13行,而不是19行。无论如何,非常感谢! - user16309118
显示剩余5条评论

1

复制你的数据后,

>>> df
                                                         patient.drug
0  [{'drugcharacterization': '1', 'medicinalproduct': 'PANDOL'}]
1  [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}]
2  [{'drugcharacterization': '3', 'medicinalproduct': 'SIMVASTATIN'}]
3  [{'drugcharacterization': '3', 'medicinalproduct': 'SIMVASTATIN'}]
4  [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}]

在使用您的代码时:
>>> df[df['patient.drug'].str.contains('NIFEDIPINE')]

错误:

    raise KeyError(f"None of [{key}] are in the [{axis_name}]")
KeyError: "None of [Float64Index([nan, nan, nan, nan, nan], dtype='float64')] are in the [columns]"

解决方案:
    >>> df[df['patient.drug'].astype('str').str.contains('NIFEDIPINE')]
                                                        patient.drug
1  [{'drugcharacterization': '2', 'medicinalproduct': 'NIFEDIPINE'}]
4  [{'drugcharacterization': '4', 'medicinalproduct': 'NIFEDIPINE'}]

注意:
这是由于pandas中indexer.py部分的索引检查引起的问题,如下所示:
---> pandas/core/indexing.py
# Count missing values:
missing_mask = indexer < 0
missing = (missing_mask).sum()

if missing:
    if missing == len(indexer):
        axis_name = self.obj._get_axis_name(axis)
        raise KeyError(f"None of [{key}] are in the [{axis_name}]")

    # We (temporarily) allow for some missing keys with .loc, except in
    # some cases (e.g. setting) in which "raise_missing" will be False

0

不清楚您的列的每个元素是字典列表还是仅仅是字典。无论如何,我都为两种情况提供了解决方案。

  1. 如果列的每个元素是字典,则尝试以下方法:
import pandas as pd

a = [1, 2, 3, 4, 6]
b = [{'a':'A'}, {'b':'B'}, {'c':'C'}, {'d':'D'}, {'e':'E'}]
df = pd.DataFrame({'A': a, 'B': b})

df[df['B'].apply(lambda x: 'a' in x)]

这将输出:

A   B
1   {'a': 'A'}

在你的情况下

df[df['B'].apply(lambda x: 'NIFEDIPINE' in x)]

如果每个列元素都是字典列表,请尝试以下操作:
import pandas as pd

a = [1, 2, 3, 4, 6]
b = [[{'a':'A'}], [{'b':'B'}], [{'c':'C'}], [{'d':'D'}], [{'e':'E'}]]
df = pd.DataFrame({'A': a, 'B': b})

def check(key, dict_list):
  for map in dict_list:
    if key in map:
      return True
  return False

df[df['B'].apply(lambda x: check('a', x))]

0

你可以使用 isin

drug_name = ['NIFEDIPINE']

df_NIFEDIPINE = df[df['patient.drug'].isin(drug_name)].reset_index()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接