从 pandas.DataFrame 中使用复杂标准进行选择

2024-12-11 08:48:00
admin
原创
165
摘要:问题描述:例如我有简单的 DF:import pandas as pd from random import randint df = pd.DataFrame({'A': [randint(1, 9) for x in range(10)], 'B': [randin...

问题描述:

例如我有简单的 DF:

import pandas as pd
from random import randint

df = pd.DataFrame({'A': [randint(1, 9) for x in range(10)],
                   'B': [randint(1, 9)*10 for x in range(10)],
                   'C': [randint(1, 9)*100 for x in range(10)]})

我可以使用 Pandas 的方法和习语从“A”中选择出与“B”对应的值大于 50,与“C”对应的值不等于 900 吗?


解决方案 1:

当然可以!设置:

>>> import pandas as pd
>>> from random import randint
>>> df = pd.DataFrame({'A': [randint(1, 9) for x in range(10)],
                   'B': [randint(1, 9)*10 for x in range(10)],
                   'C': [randint(1, 9)*100 for x in range(10)]})
>>> df
   A   B    C
0  9  40  300
1  9  70  700
2  5  70  900
3  8  80  900
4  7  50  200
5  9  30  900
6  2  80  700
7  2  80  400
8  5  80  300
9  7  70  800

我们可以应用列操作并获取布尔 Series 对象:

>>> df["B"] > 50
0    False
1     True
2     True
3     True
4    False
5    False
6     True
7     True
8     True
9     True
Name: B
>>> (df["B"] > 50) & (df["C"] != 900)

或者

>>> (df["B"] > 50) & ~(df["C"] == 900)
0    False
1    False
2     True
3     True
4    False
5    False
6    False
7    False
8    False
9    False

[更新,切换到新样式.loc]:

然后我们可以使用这些来索引对象。对于读取访问,您可以链接索引:

>>> df["A"][(df["B"] > 50) & (df["C"] != 900)]
2    5
3    8
Name: A, dtype: int64

但是,由于视图和副本执行此操作以获得写访问权限之间存在差异,因此您可能会陷入麻烦。您可以改用.loc

>>> df.loc[(df["B"] > 50) & (df["C"] != 900), "A"]
2    5
3    8
Name: A, dtype: int64
>>> df.loc[(df["B"] > 50) & (df["C"] != 900), "A"].values
array([5, 8], dtype=int64)
>>> df.loc[(df["B"] > 50) & (df["C"] != 900), "A"] *= 1000
>>> df
      A   B    C
0     9  40  300
1     9  70  700
2  5000  70  900
3  8000  80  900
4     7  50  200
5     9  30  900
6     2  80  700
7     2  80  400
8     5  80  300
9     7  70  800

解决方案 2:

另一种解决方案是使用查询方法:

import pandas as pd

from random import randint
df = pd.DataFrame({'A': [randint(1, 9) for x in xrange(10)],
                   'B': [randint(1, 9) * 10 for x in xrange(10)],
                   'C': [randint(1, 9) * 100 for x in xrange(10)]})
print df

   A   B    C
0  7  20  300
1  7  80  700
2  4  90  100
3  4  30  900
4  7  80  200
5  7  60  800
6  3  80  900
7  9  40  100
8  6  40  100
9  3  10  600

print df.query('B > 50 and C != 900')

   A   B    C
1  7  80  700
2  4  90  100
4  7  80  200
5  7  60  800

现在,如果您想更改 A 列中的返回值,您可以保存它们的索引:

my_query_index = df.query('B > 50 & C != 900').index

....并用来.iloc改变它们,即:

df.iloc[my_query_index, 0] = 5000

print df

      A   B    C
0     7  20  300
1  5000  80  700
2  5000  90  100
3     4  30  900
4  5000  80  200
5  5000  60  800
6     3  80  900
7     9  40  100
8     6  40  100
9     3  10  600

解决方案 3:

记得使用括号!

请记住,&运算符优先于诸如><等运算符。这就是为什么

4 < 5 & 6 > 4

计算结果为False。因此,如果您使用pd.loc,则需要将逻辑语句括在括号中,否则会出错。这就是为什么这样做的原因:

df.loc[(df['A'] > 10) & (df['B'] < 15)]

而不是

df.loc[df['A'] > 10 & df['B'] < 15]

这将导致

TypeError:无法将 dtyped [float64] 数组与类型为 [bool] 的标量进行比较

解决方案 4:

您可以使用 pandas,它有一些内置函数用于比较。因此,如果您想选择满足“B”和“C”条件的“A”值(假设您想要返回 DataFrame pandas 对象)

df[['A']][df.B.gt(50) & df.C.ne(900)]

df[['A']]将以 DataFrame 格式返回 A 列。

pandasgt函数将返回 B 列中大于 50 的位置,并ne返回不等于 900 的位置。

解决方案 5:

将每个条件分配给一个变量可能会更具可读性,特别是当它们有很多(可能具有描述性名称)并使用按位运算符(例如 (&|)将它们链接在一起时。另外,您无需担心括号,()因为每个条件都是独立评估的。

m1 = df['B'] > 50
m2 = df['C'] != 900
m3 = df['C'].pow(2) > 1000
m4 = df['B'].mul(4).between(50, 500)

# filter rows where all of the conditions are True
df[m1 & m2 & m3 & m4]

# filter rows of column A where all of the conditions are True
df.loc[m1 & m2 & m3 & m4, 'A']

或者将条件放在列表中并通过bitwise_andfrom numpy(包装器&)减少它。

conditions = [
    df['B'] > 50,
    df['C'] != 900,
    df['C'].pow(2) > 1000,
    df['B'].mul(4).between(50, 500)
]
# filter rows of A where all of conditions are True
df.loc[np.bitwise_and.reduce(conditions), 'A']
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   27  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   22  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   19  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用