如何通过字符串列指定位置的单个字符筛选Pandas DataFrame
问题说明
现有如下结构的Pandas DataFrame:
event列:存储事件名称day列:存储长度为7的二进制字符串,用于标记事件对应的发生周几:字符串第1位(索引0)代表周一,最后1位(索引6)代表周日,字符为1表示当日有事件,0表示当日无事件
示例数据如下:
event day 0 A 1000010 1 B 1010100 2 C 0100010 3 D 0000011
编码规则示例:
- 事件A的
day值为1000010,对应周一、周六发生 - 事件B的
day值为1010100,对应周一、周三、周五发生 - 事件D的
day值为0000011,对应周六、周日发生
注:该二进制字符串存储格式是为了兼容此前Bash+Awk的处理流程,后续拓展需要保留该存储格式。
需求描述
需要实现基于day列指定位置字符筛选行的功能:例如筛选所有周六有事件的行,逻辑等价于逐行判断day字符串的第5位(索引从0开始计数)是否等于"1",预期返回索引为2、3的行(对应事件C、D)。
此前尝试的df.loc[(df['day'][5]=="1")]写法无法实现逐行取字符串指定位置的筛选效果。
解决方法
之前写法无效的核心原因:df['day'][5]的逻辑是取day列的第5行元素,不是逐行提取每个字符串的第5位字符。要实现逐行的字符串索引操作,需要调用Pandas的字符串访问器.str。
单天筛选写法
以筛选周六(对应字符串索引5)有事件的行为例,正确代码如下:
# 逐行提取day字符串索引为5的字符,判断是否为"1" saturday_event = df.loc[df['day'].str[5] == "1"]
运行后得到的结果完全符合预期:
event day 2 C 0100010 3 D 0000011
通用规则
要筛选其他周几的事件,只需要替换对应位置的索引值即可:
- 筛选周一有事件:
df.loc[df['day'].str[0] == "1"] - 筛选周二有事件:
df.loc[df['day'].str[1] == "1"] - 筛选周三有事件:
df.loc[df['day'].str[2] == "1"] - 筛选周四有事件:
df.loc[df['day'].str[3] == "1"] - 筛选周五有事件:
df.loc[df['day'].str[4] == "1"] - 筛选周日有事件:
df.loc[df['day'].str[6] == "1"]
如果需要筛选同时满足多天有事件的行,用&拼接多个判断条件即可,注意每个单独的判断条件必须用圆括号包裹,避免运算优先级报错,例如筛选周一、周六同时有事件的行:
mon_sat_event = df.loc[(df['day'].str[0] == "1") & (df['day'].str[5] == "1")]
提示:如果你的
day列存在缺失值,.str访问器会自动在对应位置返回空值,筛选时会自动排除这些行,不会抛出异常。
内容的提问来源于stack exchange,提问作者Max Kapusta
相关产品推荐
相关产品推荐

