­

pandas踩过的坑 | 记一个群友的提问

  • 2019 年 12 月 26 日
  • 筆記

今天群里小伙伴提问了一个问题,下面这个图如何加上表头?

群里的每一次提问,都是一次面试,如果可以,我都会尝试解答。这里只晒了一张图,没有上下文,我提示代码不全,小伙伴后来补充了相关代码和报错:

根据报错提示,这里的对象 bSeries 类型,热心的小伙伴给出了解决方案:

1、b=pd.DataFrame(b)

2、b=b.reset_index(drop=False)

很快,小伙伴就去跑代码了,得出了下图结果:

很明显,这里的列名错位了,热心的小伙伴马上给出了解决方案:

①:保存时不写入index ②:rename ③:输出时:Index= False

下面是小伙伴给出的完整代码示例:

df.columns Index(['时间', 'Enodeb标识符', 'Enodeb中文名称', '厂家名称', '管理状态', '设备维护状态', '运行状态', '工程编号'], dtype='object') df.head() 时间 Enodeb标识符 … 运行状态 工程编号 0 2019/11/28 0:00:00 460-00-200188 … ENABLED 一期 1 2019/11/28 0:00:00 460-00-211503 … ENABLED 四期 2 2019/11/28 0:00:00 460-00-686652 … ENABLED 四期 3 2019/11/28 0:00:00 460-00-732426 … ENABLED 4G网络优化扩容2018年三阶段-新建P1 4 2019/11/28 0:00:00 460-00-518238 … ENABLED 蜂窝物联网一期工程P1 [5 rows x 8 columns] df['运行状态'].value_counts() ENABLED 58056 DISABLED 852 Name: 运行状态, dtype: int64 df1=df['运行状态'].value_counts() type(df1) df1.name '运行状态' df1.index Index(['ENABLED', 'DISABLED'], dtype='object') df2=pd.DataFrame(df1) type(df2) df2.columns Index(['运行状态'], dtype='object') df2.index Index(['ENABLED', 'DISABLED'], dtype='object') df3=df2.reset_index(drop=False) df3.columns Index(['index', '运行状态'], dtype='object') df3.index RangeIndex(start=0, stop=2, step=1) df3 index 运行状态 0 ENABLED 58056 1 DISABLED 852 df3.rename(columns={'index':'运行状态','运行状态':'计数'},inplace=True) df3 运行状态 计数 0 ENABLED 58056 1 DISABLED 852 df3.to_csv('运行状态统计.csv',encoding='GBK',index=False)

我给出的解决方案被证明是错的:

b.to_csv('as.csv', encoding='gbk', header=['cellname', 'cnt'])

SeriesDataFrame的方案,代码过于复杂了,下面是热心群友给出的简洁方案:

df1=df['运行状态'].value_counts()  df1.name='计数'  df1.to_csv('运行状态3.csv',encoding='GBK',index=True,header=True,index_label='运行状态2')

咱们来理一理,感觉Series直接输出csv并且保留表头很难搞的样子。

从我给出的错误代码入手,Series是数据序列,仅有一列数据,表象上看是两列,因为有一列是index,我给出的代码包含header=[ 'cellname', 'cnt'],误解为表头有两列,所以是错误的,下面通过一个简单的示例复盘下整个过程。

import pandas as pd    df = pd.read_csv(r'D:abc.csv')  
df  

name

value

0

a

1

1

b

2

2

c

3

3

a

1

4

b

2

5

c

3

6

a

1

7

b

2

8

c

3

群友是要计算某列的计数

df2 = df['name'].value_counts()  
df2  
b    3  c    3  a    3  Name: name, dtype: int64  
type(df2)  
pandas.core.series.Series  
df2.index  
Index(['b', 'c', 'a'], dtype='object')  
df2.name  
'name'  

可以看出,Series呈现出两列数据,左边是index,右边是数据列, 该数据列的内容对应index的计数,但是列名却是name,输出时需要修正一下,此处,Series的两列内容我们都想获取到,所以index=Trueindex内容对应原表的name,所以,index_label应该设置为name,而数据列的表头对应index的计数,所以header应该设置为count,至此,代码呼之欲出:

df2.to_csv(r'D:/abc2.csv', index=True, index_label='name', header=[ 'count'])  

来看一下是否得到的预期的结果