【问题标题】:How to query between the values of two columns of a data frame如何在数据框的两列的值之间进行查询
【发布时间】:2019-11-20 12:49:47
【问题描述】:

假设我有一个包含以下列的数据框,

df.head()
    ref_loc ref_chr REF ALT coverage    base
    9532728 21  G   [A] 1   A
    9540473 21  C   [G] 2   G
    9540473 21  CTATT   [C] 2   G
    9540794 21  C   [T] 1   A
    9542965 21  C   [A] 1   T

我想将ALT 列与base 列进行比较,看看匹配和差异。根据匹配和差异,我想生成一个名为cate 的新列。

为此,我尝试使用以下功能,

def grouping(row):
    if row['ALT'] == row['base']:
         val = "same_variants"
    elif row['ALT'] != row['base']:
         val = "diff_variants"
    return val

df["cate"] = df.apply(grouping,axis=0)

但是,该函数在尝试应用于数据帧时会抛出此错误,

    KeyError                                  Traceback (most recent call last)
<ipython-input-13-a265dee72ec1> in <module>
----> 1 df["group"] =df.apply(grouping,axis=0)

~/software/anaconda/lib/python3.7/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, result_type, args, **kwds)
   6911             kwds=kwds,
   6912         )
-> 6913         return op.get_result()
   6914 
   6915     def applymap(self, func):

~/software/anaconda/lib/python3.7/site-packages/pandas/core/apply.py in get_result(self)
    184             return self.apply_raw()
    185 
--> 186         return self.apply_standard()
    187 
    188     def apply_empty_result(self):

~/software/anaconda/lib/python3.7/site-packages/pandas/core/apply.py in apply_standard(self)
    290 
    291         # compute the result using the series generator
--> 292         self.apply_series_generator()
    293 
    294         # wrap results

~/software/anaconda/lib/python3.7/site-packages/pandas/core/apply.py in apply_series_generator(self)
    319             try:
    320                 for i, v in enumerate(series_gen):
--> 321                     results[i] = self.f(v)
    322                     keys.append(v.name)
    323             except Exception as e:

<ipython-input-11-098066170c2f> in grouping(row)
      1 def grouping(row):
----> 2     if row['ALT'] == row['base']:
      3          val = "same_variants"
      4     elif row['ALT'] != row['base']:
      5          val= "diff_variants"

~/software/anaconda/lib/python3.7/site-packages/pandas/core/series.py in __getitem__(self, key)
   1066         key = com.apply_if_callable(key, self)
   1067         try:
-> 1068             result = self.index.get_value(self, key)
   1069 
   1070             if not is_scalar(result):

~/software/anaconda/lib/python3.7/site-packages/pandas/core/indexes/base.py in get_value(self, series, key)
   4728         k = self._convert_scalar_indexer(k, kind="getitem")
   4729         try:
-> 4730             return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
   4731         except KeyError as e1:
   4732             if len(self) > 0 and (self.holds_integer() or self.is_boolean()):

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_value()

pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc()

pandas/_libs/index_class_helper.pxi in pandas._libs.index.Int64Engine._check_type()

KeyError: ('ALT', 'occurred at index ref_loc')

我想提出一些可以继续前进的建议。

最后,输出应该如下所示,

ref_loc ref_chr REF ALT coverage    base    cate
9532728 21  G   [A]      1         A      same_variants
9540473 21  C   [G]      2         G      same_variants
9540473 21  CTATT   [C]  2         G      diff_variants
9540794 21  C   [T]      1         A      diff_variants
9542965 21  C   [A]      1         T      diff_variants

【问题讨论】:

    标签: python pandas function lambda


    【解决方案1】:

    请注意,由于ALT 列周围有方括号,所以它总是不同的。您可以先提取括号内的内容:
    df["ALT"] = df.ALT.apply(lambda l: l[0])

    您需要使用axis=1 来遍历行。 axis=0 遍历列。

    df["cate"] = df.apply(grouping,axis=1)
    print(df)
    
       ref_loc  ref_chr    REF ALT  coverage base           cate
    0  9532728       21      G   A         1    A  same_variants
    1  9540473       21      C   G         2    G  same_variants
    2  9540473       21  CTATT   C         2    G  diff_variants
    3  9540794       21      C   T         1    A  diff_variants
    4  9542965       21      C   A         1    T  diff_variants
    

    【讨论】:

    • 我的错,我没注意到axis=0,部分:P,谢谢!
    • 但是,当您使用df["ALT"] = df.ALT.str.extract('\[(.*)\]') 删除方括号时。然后它删除值并添加NaN
    • 啊,那么您的 ALT 列中必须有列表。我编辑了答案以考虑到这一点,现在可行吗?
    【解决方案2】:

    你需要将你的函数应用到每一行:

    df["cate"] = df.apply(grouping, axis=1)
    

    如果我理解正确,ALT 列包含列表。所以你需要访问每个列表的第一个元素:

    def grouping(row):
        if row['ALT'][0] == row['base']:
             return "same_variants"
        else:
             return "diff_variants"
    

    或者,您可以使用numpy 函数where

    df['cate'] = np.where(df['ALT'].str[0]==df['base'], 'same_variants', 'diff_variants')
    

    【讨论】:

      【解决方案3】:

      尽管这是一种不同的方法,但我认为值得一提的是:您可以使用这种单线实现它:

      df['cate'] = np.where(df['ALT'] == '['+df['base']+']', 'same_variants', 'diff_variants')
      

      我尝试在比较右侧使用format,但无济于事。

      【讨论】:

        猜你喜欢
        • 2018-03-29
        • 2018-03-21
        • 2018-03-19
        • 2014-01-14
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        • 2020-04-30
        • 1970-01-01
        相关资源
        最近更新 更多