如何统计Pandas DataFrame列子集的返回行数?
当选取Pandas DataFrame的列子集时,如何统计返回的行数?
我太懂这种头疼的情况了!当你从Pandas DataFrame里筛选列子集时,结果行数不一样,处理逻辑居然还会变——多行的时候能正常获取行数,单行的时候直接调用shape或者len()就报错,简直让人摸不着头脑。
先看个实际例子,你就能立刻明白问题出在哪:
import pandas as pd # 创建测试数据 df1 = pd.DataFrame({'A':['A1','A2','A1'],'B':['B1','B2','B3']}) df2 = df1.set_index('A') df3 = df1.iloc[:2,].set_index('A')
先看下两个DataFrame的结构:
>>> df2 B A A1 B1 A2 B2 A1 B3 >>> df3 B A A1 B1 A2 B2
现在尝试获取匹配行的形状:
# 匹配到两行时,返回Series对象,能正常调用shape >>> df2.loc['A1','B'].shape (2,) # 但匹配到一行时,返回的是字符串标量,调用shape直接报错 >>> df3.loc['A1','B'].shape Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'str' object has no attribute 'shape'
问题根源
这其实是Pandas的默认“简化”行为:当你的筛选结果包含多行时,它会返回一个Series对象,这时候可以正常用shape、len()统计行数;但如果结果只有一行,Pandas会自动把它简化成对应的标量值(比如这里的字符串'B1'),标量自然没有shape或者len()这些属性。
我们可以对比两种情况的返回值:
>>> df2.loc['A1','B'] # 返回Series A A1 B1 A1 B3 Name: B, dtype: object >>> df3.loc['A1','B'] # 返回标量字符串 'B1'
解决办法
这里有几个靠谱的方案,能让你不管结果是一行还是多行,都能稳定统计行数:
- 方案一:使用
keepdims=True参数
在loc查询时加上这个参数,强制Pandas返回二维的DataFrame,哪怕只有一行数据:
df3.loc['A1','B', keepdims=True].shape
(1, 1)
len(df3.loc['A1','B', keepdims=True])
1
- **方案二:用双层方括号选取列** 选取列的时候用`[[列名]]`替代`列名`,这样返回的始终是DataFrame,不会被简化成标量: ```python >>> df3.loc['A1', ['B']].shape (1, 1) >>> len(df3.loc['A1', ['B']]) 1
- 方案三:统一转成Series处理
不管返回的是标量还是Series,都用pd.Series()包装一下,这样就能统一调用shape或者len():
result = df3.loc['A1','B']
pd.Series(result).shape
(1,)
len(pd.Series(result))
1
内容的提问来源于stack exchange,提问作者KClem
相关产品推荐
相关产品推荐

