【问题标题】:More effective way to use pandas get_loc?使用pandas get_loc的更有效方法?
【发布时间】:2018-08-01 08:07:50
【问题描述】:

任务:在多列数据框中搜索一个值(所有值都是唯一的)并返回该行的索引。

目前: 使用 get_loc,但似乎一次只允许传递一个列,导致一组非常无效的 try except 语句。虽然它有效,但有人知道更有效的方法吗?

df =  pd.DataFrame(np.random.randint(0,100,size=(4, 4)), columns=list('ABCD'))
try: 
     unique_index = pd.Index(df['A'])
     print(unique_index.get_loc(20))
except KeyError:
    try: 
        unique_index = pd.Index(df['B'])
        print(unique_index.get_loc(20))
    except KeyError:
                unique_index = pd.Index(df['C'])
                print(unique_index.get_loc(20))

循环似乎不起作用,因为如果列不包含值,则会引发 KeyError。我查看了诸如 .contains 或 .isin 之类的函数,但它是我感兴趣的位置索引。

【问题讨论】:

  • 在此示例中,您是否在整个数据框中寻找值 20?
  • 是的,但是因为它是 np.random.randint,所以值可以是任何值。只是我正在使用的一个例子

标签: python pandas indexing


【解决方案1】:

您可以使用np.where,它返回一个包含您的值的行和列索引的元组。然后,您可以从中仅选择行。

df =  pd.DataFrame(np.random.randint(0,100,size=(4, 4)), columns=list('ABCD'))
indices = np.where(df.values == 20)
rows = indices[0]
if len(rows) != 0:
    print(rows[0])

【讨论】:

  • 接受这个作为答案,尽管@piRiSquared 的答案是正确的。这为我提供了我需要的确切结果。
【解决方案2】:

考虑这个例子,而不是使用np.random.seed

np.random.seed([3, 1415])
df = pd.DataFrame(
    np.random.randint(200 ,size=(4, 4)),
    columns=list('ABCD'))

df

     A    B    C    D
0   11   98  123   90
1  143  126   55  141
2  139  141  154  115
3   63  104  128  120

我们可以使用np.where 和切片找到您要查找的值。请注意,我使用了55 的值,因为这是我从我选择的种子中获得的数据中的内容。如果 20 在您的数据集中,这将适用于它。事实上,如果你有多个,它会起作用。

i, j = np.where(df.values == 55)
list(zip(df.index[i], df.columns[j]))

[(1, 'C')]

【讨论】:

    【解决方案3】:

    使用矢量化操作和布尔索引:

    df[(df==20).any(axis=1)].index
    

    【讨论】:

    • 啊!这是我错过的两个解决方案。你更快;)
    【解决方案4】:

    另一种方式

    df[df.eq(20)].stack()
    Out[1220]: 
    1  C    20.0
    dtype: float64
    

    【讨论】:

      【解决方案5】:

      由于其他海报使用np.where(),我将提供另一个选项使用any()

      df.loc[df.isin([20]).any(axis=1)].index
      

      由于df.loc[*condition_here*] 将在满足条件时返回 TRUE,因此您可以使用 any 过滤到可能为 true 的行

      所以这是我的 df 示例:

          A   B   C   D
      0   82  7   48  90
      1   68  18  90  14 #< ---- notice the 18 here
      2   18  34  72  24 #< ---- notice the 18 here
      3   69  73  40  86
      
      df.isin([18])
      
          A   B   C   D
      0   False   False   False   False
      1   False   True    False   False  #<- ---- notice the TRUE value
      2   True    False   False   False  #<- ---- notice the TRUE value
      3   False   False   False   False
      
      
      print(df.loc[df.isin([18]).any(axis=1)].index.tolist())
      #output is a list
      [1, 2]
      

      【讨论】:

      • @F.D,我添加了输出。我使用tolist() 为您提供了满足条件的索引列表
      猜你喜欢
      • 1970-01-01
      • 2016-10-08
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多