代码之家  ›  专栏  ›  技术社区  ›  Dinesh

根据单元格值的列表检索数据帧行

  •  0
  • Dinesh  · 技术社区  · 5 年前

    我正试图从pandas数据框中检索一行,其中单元格值是一个列表。我试过了 isin ,但看起来它正在执行或操作,而不是和操作。

    >>> import pandas as pd
    >>> df = pd.DataFrame([['100', 'RB','stacked'], [['101','102'], 'CC','tagged'], ['102', 'S+C','tagged']],
        columns=['vlan_id', 'mode' ,    'tag_mode'],index=['dinesh','vj','mani'])
    
    >>> df
               vlan_id  mode  tag_mode
    dinesh         100   RB  stacked
    vj      [101, 102]   CC   tagged
    mani           102  S+C   tagged
    
    >>> df.loc[df['vlan_id'] == '102']; # Fetching string value match
          vlan_id mode tag_mode
    mani     102  S+C   tagged
    
    >>> df.loc[df['vlan_id'].isin(['100','102'])]; # Fetching if contains either 100 or 102
    
           vlan_id mode tag_mode
    dinesh     100   RB  stacked
    mani       102  S+C   tagged
    >>> df.loc[df['vlan_id'] == ['101','102']]; # Fails ? 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Python27\lib\site-packages\pandas\core\ops.py", line 1283, in wrapper
        res = na_op(values, other)
      File "C:\Python27\lib\site-packages\pandas\core\ops.py", line 1143, in na_op
        result = _comp_method_OBJECT_ARRAY(op, x, y)
      File "C:\Python27\lib\site-packages\pandas\core\ops.py", line 1120, in _comp_method_OBJECT_ARRAY
        result = libops.vec_compare(x, y, op)
      File "pandas\_libs\ops.pyx", line 128, in pandas._libs.ops.vec_compare
    ValueError: Arrays were different lengths: 3 vs 2
    

    我可以把这些值放到一个列表中并进行比较。相反,是否有任何方法可以根据列表值使用 .loc 方法本身?

    3 回复  |  直到 5 年前
        1
  •  2
  •   Mohit Motwani    5 年前

    要查找列表,可以迭代 vlan_id 并使用比较每个值 np.array_equal :

    df.loc[[np.array_equal(x, ['101','102']) for x in df.vlan_id.values]]
    
    
         vlan_id    mode    tag_mode
    vj  [101, 102]  CC       tagged
    

    不过,建议不要在数据帧中将列表用作单元格值。

    DataFrame.loc 可以使用标签列表或布尔数组访问行和列。上面的列表理解构造了一个布尔数组。

        2
  •  0
  •   gmds    5 年前

    我不确定这是最好的方法还是 好的 就我所知,这样做的方法 pandas 不支持存储 lists 在里面 Series . 仍然:

    l = ['101', '102']
    
    df.loc[pd.concat([df['vlan_id'].str[i] == l[i] for i in range(len(l))], axis=1).all(axis=1)]
    

    输出:

           vlan_id mode tag_mode
    vj  [101, 102]   CC   tagged
    
        3
  •  0
  •   dvitsios    5 年前

    另一个解决方法是改变 vlan_id 列,以便它可以作为字符串进行查询。你可以加入你的 弗兰尼德 将值列出为逗号分隔的字符串。

    df['proxy'] = df['vlan_id'].apply(lambda x: ','.join(x) if type(x) is list else ','.join([x]) )
    
    l = ','.join(['101', '102'])
    print(df.loc[df['proxy'] == l])