【问题标题】:filter out rows of a dataframe containing a specific string过滤掉包含特定字符串的数据帧的行
【发布时间】:2021-09-08 13:18:55
【问题描述】:

我有一个庞大的数据框。数据框有列患者.药物。此列包含字典列表作为其元素。 我想过滤掉 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:
  • df[df['patient.drug'].str.contains('NIFEDIPINE')] ??
  • 这能回答你的问题吗? pandas dataframe str.contains() AND operation
  • 似乎您在patient.drug 列中有(很多)NaNs。所以请尝试df[df["patient.drug"].str.contains("NIFEDIPINE", na=False)],它会在返回值中说NaNs 是False,而不是它们自己,然后你可以希望安全地将其用作掩码。
  • 您能否包含一个数据框的小样本?这将使您的问题和期望的输出更加清晰。

标签: python pandas dataframe data-science


【解决方案1】:

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

  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)]
  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})

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))]

【讨论】:

    【解决方案2】:

    您可以使用isin

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

    【讨论】:

      【解决方案3】:

      假设你有这样的列布局:

      在第 2 和第 4 个条目中找到搜索字符串“NIFEDIPINE”:

      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) 支持列表中的多个 dict 和 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: cannot reindex from a duplicate axis
      • @user16309118,你的dataFrame和他的回答中显示的SeaBean一样吗?
      • @KarnKumar 是的,我在问题中添加了一个示例。
      • @user16309118 列表中是否有一些条目可以有多个字典?
      • @user16309118 见我上面的编辑。现在支持列表中的多个字典。请重试。
      【解决方案4】:

      复制您的数据后,

      >>> 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'}]
      

      注意:

      这是由于indexer 在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
      

      【讨论】:

        猜你喜欢
        • 2014-05-16
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        • 1970-01-01
        • 2018-11-02
        • 1970-01-01
        • 2021-12-21
        相关资源
        最近更新 更多