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'])  

來看一下是否得到的預期的結果