V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
badacook
V2EX  ›  Python

pandas.DataFrame 的列筛选

  •  
  •   badacook · 2021-03-23 20:35:37 +08:00 · 2241 次点击
    这是一个创建于 1344 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大家好 在使用 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 数据筛选的前辈 指点一下 关于多列组合条件 筛选的实现方法,小弟不胜感激。
    17 条回复    2021-03-26 09:47:42 +08:00
    badacook
        1
    badacook  
    OP
       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
        2
    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
        3
    lizliz  
       2021-03-23 22:48:39 +08:00
    @badacook 我都是这么操作的,基本上就是这样了吧,没见过其他操作
    bigtan
        4
    bigtan  
       2021-03-23 22:59:13 +08:00
    np.logical_and/or 我比较喜欢这个
    badacook
        5
    badacook  
    OP
       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
        6
    badacook  
    OP
       2021-03-24 00:10:35 +08:00
    @noqwerty 非常感谢你分享的文档链接,哈哈哈其实今天是第一天 开始用 pandas 库,API 文档都是 今天别人分享给我后查到这么处理的,要是早看到 你的分享 就不用试这么久了,还是非常感谢了
    noqwerty
        7
    noqwerty  
       2021-03-24 00:23:26 +08:00
    @badacook #5 result[(result["code"].str.contains(pat1)) & (~result["code_name"].str.contains(pat2))]
    badacook
        8
    badacook  
    OP
       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
        9
    noqwerty  
       2021-03-24 00:48:26 +08:00
    @badacook #8 真的建议你好好翻一下文档 😂 Google 出来的前两条都是你要的答案 https://stackoverflow.com/questions/26763344/convert-pandas-column-to-datetime
    badacook
        10
    badacook  
    OP
       2021-03-24 08:20:28 +08:00
    @noqwerty 哈哈哈 昨天有看文档 都是 展示的 datetime 数据格式化输出的,就想到了问大佬了
    多谢大佬 最近可能是 google 不太好使,就忘了这一茬了,一定改正 改正
    bigtan
        11
    bigtan  
       2021-03-24 08:27:45 +08:00
    numpy.logical_not
    lizliz
        12
    lizliz  
       2021-03-24 09:02:18 +08:00
    取反就是~
    zyb201314
        13
    zyb201314  
       2021-03-24 09:52:48 +08:00 via Android
    print(result[result.code.str.contains("sz")&result.code_name.str.contains("B")])
    princelai
        14
    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
        15
    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
        16
    badacook  
    OP
       2021-03-26 08:43:13 +08:00
    @princelai 很抱歉 经查询 pandas.DataFrame.query 语法,并验证你提供的 答案报错,不过还是谢谢你的回复
    princelai
        17
    princelai  
       2021-03-26 09:47:42 +08:00
    @badacook #16 表达式内引用外部数据要用 @引用符,你这里可能要改为 @pat1,@pat2 试试
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4280 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 01:01 · PVG 09:01 · LAX 17:01 · JFK 20:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.