【问题标题】:Lookup a single value using a multi-column key from Pandas DataFrame使用 Pandas DataFrame 中的多列键查找单个值
【发布时间】:2021-07-13 22:19:13
【问题描述】:

这个帖子似乎没有涵盖我经常遇到的情况。

Return single cell value from Pandas DataFrame

如何使用一组列条件作为键返回单个值,而不是系列或数据框?这似乎是一个普遍的需求。假设您有一个信息数据库,您需要从中提取问题的答案,但您需要一个答案,而不是一系列可能的答案。我的方法似乎“做作”——不是 Pythonic?而且可能由于技术原因不好。

import pandas as pd
d = {'A': [1, 1, 1, 2, 2, 2, 3, 3, 3], 'B': [1, 2, 3, 1, 2, 3, 1, 2, 3], 'C': [1, 3, 5, 
     2, 9, 7, 4, 3, 2]}
df = pd.DataFrame(data=d)

df 看起来像:

        A   B   C
    0   1   1   1
    1   1   2   3
    2   1   3   5
    3   2   1   2
    4   2   2   9
    5   2   3   7
    6   3   1   4
    7   3   2   3
    8   3   3   2

如何获取A == 1和B == 3的C列中的值?在我的情况下,它总是唯一的,但我可以看到这是不能假设的,所以这个方法返回一个系列:

df[(df['A'] == 1) & (df['B'] == 3)]['C']

我不想要一个系列。那么如何获取单个值,而不是一行或一个元素的系列或列表?

我的方法:

df[(df['A'] == 1) & (df['B'] == 3)]['C'].tolist()[0]

在 Pandas 库中,DataFrame.at 似乎是要走的路,但这种方法看起来并不好,但我想知道它在技术上是否更好:

df.at[df.loc[(df['A'] == 1) & (df['B'] == 3)].index[0], 'C']

那么,在您看来,使用多列条件在数据框中查找值并返回单个值(不是列表或系列)的最佳方法是什么?

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

过去,我曾几次坐过同样的问题。我已经开始接受我这样做实际上并不常见,所以我通常只是这样做:

df.loc[(df['A'] == 1) & (df['B'] == 3), "C"].iat[0]

# frequently I also like to make it more readable like this
is1and3 = (df['A'] == 1) & (df['B'] == 3)
df.loc[is1and3, "C"].iat[0]

这几乎是一样的

df.at[df.loc[(df['A'] == 1) & (df['B'] == 3)].index[0], 'C']

它本质上只是获取与条件匹配的第一个索引并将其传递给 .at,而不是子集化然后使用 .iat[0] 获取第一个返回值,但我不太喜欢看到 .loc .index 在对.at 的调用中。

显然,pandas 需要处理的问题是,不能保证某个条件只会被 df 中的一个值满足,所以留给用户来处理。

Some basic guidance
some more in depth

【讨论】:

  • 我认为它帮助我意识到必须有一个清晰的坐标系才能在数据框中查找值,该坐标系在视觉上是二维的行和列。如果要获得特定的单个值,我需要特定的行和特定的列。这样想,我如何获得行?我已经有专栏了。 .iat 方法似乎是更 Pythonic 的选项。 df.loc 说“获取条件为真的行”,“C”选择要查找的列,而 iat[0] 说“使用该列获取返回的 df 中第一行的值”跨度>
【解决方案2】:

如果AB列的组合是唯一的,那么我们可以提前设置索引以高效检索单个值

df.set_index(['A', 'B']).loc[(1, 3), 'C']

item 的替代方法

df.loc[df['A'].eq(1) & df['B'].eq(3), 'C'].item()

【讨论】:

  • 这些都很有帮助,但我想我不应该假设它们是独一无二的,因为我的数据库中没有任何东西可以强制它。通常它是独一无二的。这些有问题,当它不是。此外,如果重复执行,df.set_index() 似乎需要更多的周期来执行。
猜你喜欢
  • 2018-08-13
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 2020-09-13
  • 2016-10-06
  • 1970-01-01
  • 2016-03-26
相关资源
最近更新 更多