pandas.DataFrame 的列筛选

2021-03-23 20:35:37 +08:00
 badacook
大家好 在使用 pandas 进行数据处理时 想实现类似中 在列标题上对表格数据进行筛选的功能
经过可以通过尝试 pandas.DataFrame.loc 函数实现,参数为 boolean array
boolean array 可以通过 DataFrame[ColumnIndexName]的 Series 的数值比较 或者 Series.str 的 contains 、startswith 、endswith 等方法获取
这取决于 DataFrame[ColumnIndexName]的 value 为数值还是 字符串,当然字符串也支持 "=="运算符,Series.str 部分方法也可支持正则表达式 使用更灵活
如果 pandas.DataFrame 想进行 多列的筛选是否 必须分步进行,不知道是否有更好的筛选方法 可以实现一步多列筛选数据
pandas.DataFrame result 实例如下 :
code code_name
0 sh.000001 上证综合指数
1 sh.000001 上证 A 股指数
2 sz.000001 上证 B 股指数
3 sh.000002 上证综合指数
4 sz.000002 上证 A 股指数
5 sz.000002 上证 B 股指数

分步筛选代码实例:
pat1 = "sz"
pat2 = "B"
result = result.loc[(result["code"].str.contains(pat1))]
result = result.loc[(result["code_name"].str.contains(pat2))]

是否可以一步直接实现多列组合条件的筛选,其中 result["code"].str.contains(pat1)与(result["code_name"].str.contains(pat2) 逻辑运算和 Series[]的逻辑运算为找到有效方法
还望有 pandas 数据筛选的前辈 指点一下 关于多列组合条件 筛选的实现方法,小弟不胜感激。
1976 次点击
所在节点    Python
17 条回复
badacook
2021-03-23 20:47:28 +08:00
居然是使用&,明明 python 中逻辑运算符 不包含这个啊,测试有效
result = result.loc[(result["code"].str.contains(pat1)) & (result["code_name"].str.contains(pat2))]
不知道 各位 还有没有其他行之有效的方法 实现 pandas 数据的并列筛选
noqwerty
2021-03-23 21:11:20 +08:00
文档里都写了的: https://pandas.pydata.org/docs/getting_started/intro_tutorials/03_subset_data.html#how-do-i-filter-specific-rows-from-a-dataframe

如果没有同时筛选列的话还可以把你的.loc 去掉
lizliz
2021-03-23 22:48:39 +08:00
@badacook 我都是这么操作的,基本上就是这样了吧,没见过其他操作
bigtan
2021-03-23 22:59:13 +08:00
np.logical_and/or 我比较喜欢这个
badacook
2021-03-24 00:06:47 +08:00
@noqwerty
@lizliz
@bigtan
现在 还遇上一个问题 如果其中一个条件需要取反 怎么表达式怎么写啊
就比如 不包含 pat2,并列筛选
result = result.loc[(result["code"].str.contains(pat1)) & (result["code_name"].str.contains(pat2))]
第二个条件 取反 如何写表达式啊,尝试了没实现 还望各位指点一下
badacook
2021-03-24 00:10:35 +08:00
@noqwerty 非常感谢你分享的文档链接,哈哈哈其实今天是第一天 开始用 pandas 库,API 文档都是 今天别人分享给我后查到这么处理的,要是早看到 你的分享 就不用试这么久了,还是非常感谢了
noqwerty
2021-03-24 00:23:26 +08:00
@badacook #5 result[(result["code"].str.contains(pat1)) & (~result["code_name"].str.contains(pat2))]
badacook
2021-03-24 00:38:49 +08:00
@noqwerty 非常感谢啊
还有一列 数据格式为 str,类似 datetime.datetime.now().strftime("%Y/%m/%d")格式
实例如下:不知道能不能 将这个 str 转换为 一个可运算的 datetime 对象,从而对该列进行筛选
ipoDate
1990/12/10
1991/1/29
不知有何好的方法啊,还望不吝赐教
noqwerty
2021-03-24 00:48:26 +08:00
@badacook #8 真的建议你好好翻一下文档 😂 Google 出来的前两条都是你要的答案 https://stackoverflow.com/questions/26763344/convert-pandas-column-to-datetime
badacook
2021-03-24 08:20:28 +08:00
@noqwerty 哈哈哈 昨天有看文档 都是 展示的 datetime 数据格式化输出的,就想到了问大佬了
多谢大佬 最近可能是 google 不太好使,就忘了这一茬了,一定改正 改正
bigtan
2021-03-24 08:27:45 +08:00
numpy.logical_not
lizliz
2021-03-24 09:02:18 +08:00
取反就是~
zyb201314
2021-03-24 09:52:48 +08:00
print(result[result.code.str.contains("sz")&result.code_name.str.contains("B")])
princelai
2021-03-24 10:08:44 +08:00
()&()方法更常用,query 方法只有在不加 engine='python'参数下才会更快,没办法,你这个必须用这样的。

```
result =result("code.str.contains(pat1) and code_name.str.contains(pat2)",engine='python')

```
princelai
2021-03-24 10:09:27 +08:00
@princelai #14
上面写错了

```
result =result.query("code.str.contains(pat1) and code_name.str.contains(pat2)",engine='python')
```
badacook
2021-03-26 08:43:13 +08:00
@princelai 很抱歉 经查询 pandas.DataFrame.query 语法,并验证你提供的 答案报错,不过还是谢谢你的回复
princelai
2021-03-26 09:47:42 +08:00
@badacook #16 表达式内引用外部数据要用 @引用符,你这里可能要改为 @pat1,@pat2 试试

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/764407

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX