1. 程式人生 > 其它 >Pandas 型別轉換之簡單求最大值及其索引

Pandas 型別轉換之簡單求最大值及其索引

技術標籤:# pandas資料分析資料分析python

目錄

簡介

Pandas Data Type

為什麼要關注dtype

一、astype and apply

方案一

方案二

方案三

二、統計哪一個sku在2019年賣出去的數量最多

1. 使用pivot_table 解決

2. 使用groupby 解決

我是總結


簡介

在做資料分析的時候,很重要的一點是要了解資料的具體型別,避免在資料分析過程中遇到奇怪的問題。
使用pandas進行資料分析時,難免會遇到需要轉換資料型別的問題。本文主要介紹pandas基本資料型別(dtype)

Pandas Data Type

Pandas dtypePython typeNumPy typeUsage
objectstr or mixedstring, unicode, mixed typesText or mixed numeric and non-numeric values
int64intint_, int8, int16, int32, int64, uint8, uint16, uint32, uint64Integer numbers
float64floatfloat_, float16, float32, float64Floating point numbers
boolboolbool_True/False values
datetime64NAdatetime64[ns]Date and time values
timedelta[ns]NANADifferences between two datetimes
categoryNANAFinite list of text values

為什麼要關注dtype

  • 使用pandas進一步資料分析之前要先檢查資料
  • 可能因為資料型別導致的報錯和錯誤的結果

本文將使用如下csv進行說明:

# data_type.csv
Sku,Views,Month,Day,Year,Sold,Reviews,Active
212039,20,2,2,2019,10,2,Y
212038,21,2,2,2018,10,2,Y
212037,22,2,2,2019,10,2,Y
212036,23,2,2,2019,10,2,Y
212035,24,2,2,2019,10,2,Y
212034,25,2,2,2019,10,2,Y
212033,26,2,2,2019,10,2,Y
212032,27,2,2,2019,10,2,Y
212031,28,2,2,2019,10,2,N
212030,29,2,2,2019,10,2,N
212039,20,3,3,2019,100,50,Y
212038,21,3,3,2019,90,48,Y
212037,22,3,3,2019,80,46,Y
212036,23,3,3,2019,70,44,Y
212035,無,3,3,2019,無,0,Y
import pandas as pd
import numpy as np
df = pd.read_csv("../datas/data_type.csv")
df
SkuViewsMonthDayYearSoldReviewsActive
021203920222019102Y
121203821222018102Y
221203722222019102Y
321203623222019102Y
421203524222019102Y
521203425222019102Y
621203326222019102Y
721203227222019102Y
821203128222019102N
921203029222019102N
102120392033201910050Y
11212038213320199048Y
12212037223320198046Y
13212036233320197044Y
142120353320190Y

df.dtypes
Sku         int64
Views      object
Month       int64
Day         int64
Year        int64
Sold       object
Reviews     int64
Active     object
dtype: object

一、astype and apply

下面介紹下astype和apply兩個函式, 具體用法可以使用help(df[‘Active’].astype)

  • astype: 型別轉換,轉換為指定的pandas data type
  • apply:將函式返回值儲存到Series中

首先將Active列轉換為bool看看發生了什麼

df['Active'].astype('bool')
0     True
1     True
2     True
3     True
4     True
5     True
6     True
7     True
8     True
9     True
10    True
11    True
12    True
13    True
14    True
Name: Active, dtype: bool

從上面結果看到所有都為True,第8和第9行也顯示了True,而期望的結果則是第8和第9行顯示False

那如何做到呢

  • 方案一: 手寫函式替換
  • 方案二: 使用lambda
  • 方案三: 使用np.where

方案一

# 方案一
def convert_bool(val):
    """
    Convert the string value to bool
     - if Y, then return True
     - if N, then return False
    """

    if val == 'Y':
        return True
    return False

df['Active'].apply(convert_bool)
0      True
1      True
2      True
3      True
4      True
5      True
6      True
7      True
8     False
9     False
10     True
11     True
12     True
13     True
14     True
Name: Active, dtype: bool

方案二

# 方案二
df["Active"].apply(lambda item: True if item=='Y' else False)
0      True
1      True
2      True
3      True
4      True
5      True
6      True
7      True
8     False
9     False
10     True
11     True
12     True
13     True
14     True
Name: Active, dtype: bool

方案三

# 方案三
np.where(df["Active"] == "Y", True, False)
# df['Active'] = np.where(df["Active"] == "Y", True, False)
array([ True,  True,  True,  True,  True,  True,  True,  True, False,
       False,  True,  True,  True,  True,  True])

二、統計哪一個sku在2019年賣出去的數量最多

  • 第一步: 統計所有sku在2019年銷售的數量之和
  • 第二步: 取出最大銷售數量的sku

1. 使用pivot_table 解決

  • 使用pivot_table函式
  • 將Sku和Year作為索引
  • Sold作為values計算
# drop if year != 2019
newdf = df.copy(deep=True)
newdf = newdf[newdf["Year"] == 2019]
pd.pivot_table(newdf, index=['Sku','Year'], values=['Sold'], aggfunc=np.sum)
Sold
SkuYear
212030201910
212031201910
212032201910
212033201910
212034201910
212035201910無
21203620191070
21203720191080
212038201990
212039201910100

從上面結果看出,sold最終結果不是我們期望的,看起來像是字串拼接,讓我們一起看看發生了什麼

首先想到的是檢查資料型別

newdf.dtypes
Sku         int64
Views      object
Month       int64
Day         int64
Year        int64
Sold       object
Reviews     int64
Active     object
dtype: object

Sold object不是int型別,所以導致np.sum計算時得到的結果不是期望的

那直接轉換成int型別???

newdf['Sold'].astype(int)
# will get follow error:
# ValueError: invalid literal for int() with base 10: '無'

毫無疑問地報錯了,這就需要我們進行資料清理,將無效資料去掉

這裡我們看一個神奇的函式

  • pd.to_numeric(arg, errors=’coerce’, downcast=None) 可以使用help函式檢視具體用法
  • If errors = ‘coerce’, then invalid parsing will be set as NaN.即解析不出來將會返回NaN
# fillna if NaN, then fill in 0.
pd.to_numeric(newdf['Sold'], errors='coerce').fillna(0)
0      10.0
2      10.0
3      10.0
4      10.0
5      10.0
6      10.0
7      10.0
8      10.0
9      10.0
10    100.0
11     90.0
12     80.0
13     70.0
14      0.0
Name: Sold, dtype: float64
# 重寫df['Sold']
# 可以看到newdf['212035']['Sold']='無' 變成了結果:0.0
newdf['Sold'] = pd.to_numeric(newdf['Sold'], errors='coerce').fillna(0)
newdf
SkuViewsMonthDayYearSoldReviewsActive
02120392022201910.02Y
22120372222201910.02Y
32120362322201910.02Y
42120352422201910.02Y
52120342522201910.02Y
62120332622201910.02Y
72120322722201910.02Y
82120312822201910.02N
92120302922201910.02N
1021203920332019100.050Y
112120382133201990.048Y
122120372233201980.046Y
132120362333201970.044Y
142120353320190.00Y

再次執行pivot_table函式

frame = pd.pivot_table(newdf, index=['Sku'], values=['Sold'], aggfunc=[np.sum])
frame
sum
Sold
Sku
21203010.0
21203110.0
21203210.0
21203310.0
21203410.0
21203510.0
21203680.0
21203790.0
21203890.0
212039110.0

獲取最大值

# 方案一
max_sold_nums = frame[('sum','Sold')].max()
# 獲取索引
max_sold_idx = frame[('sum','Sold')].idxmax()
# 獲取某一行
max_sold_infos = frame.loc[max_sold_idx]
print('Max sold numbers: \n', max_sold_nums)
print('Max sold sku details: \n', max_sold_infos)
Max sold numbers: 
 110.0
Max sold sku details: 
 sum  Sold    110.0
Name: 212039, dtype: float64
# 方案二
# 將columns的MultiIndex拆分,使用stack函式
frame.columns
MultiIndex([('sum', 'Sold')],
           )
frame.stack().reset_index()
Skulevel_1sum
0212030Sold10.0
1212031Sold10.0
2212032Sold10.0
3212033Sold10.0
4212034Sold10.0
5212035Sold10.0
6212036Sold80.0
7212037Sold90.0
8212038Sold90.0
9212039Sold110.0

single_frame = frame.stack().reset_index()
max_sold_nums = single_frame['sum'].max()
max_sold_idx = single_frame['sum'].idxmax()
max_sold_infos = single_frame.loc[max_sold_idx]
print('Max sold numbers: \n', max_sold_nums)
print('Max sold sku details: \n', max_sold_infos)
Max sold numbers: 
 110.0
Max sold sku details: 
 Sku        212039
level_1      Sold
sum           110
Name: 9, dtype: object

2. 使用groupby 解決


max_sold_nums = newdf.groupby(['Sku'])['Sold'].sum().max()
max_sold_idx = newdf.groupby(['Sku'])['Sold'].sum().idxmax()

print('Max sold numbers: \n', max_sold_nums)
print('Max sold sku: \n', max_sold_idx)
Max sold numbers: 
 110.0
Max sold sku: 
 212039

我是總結

  • 介紹了pandas的data type以及型別轉換
  • max,idxmax以及loc的用法
  • pivot_table 透視表的簡單使用
  • groupby的簡單使用

掃碼關注公眾號

掃碼關注公眾號: 風起帆揚了
來一起學習,成長,分享
航行在測試的大道上
喜歡就點贊吧