【Python】6000字、22個案例詳解Pandas數據分析/預處理時的實用技巧,超簡單
Pandas在數據預處理和數據分析方面的硬核干貨,我們大致會說Pandas計算交叉列表Pandas將字符串與數值轉化成時間類型Pandas將字符串轉化成數值類型
Pandas當中的交叉列表
Pandas模塊當中的crosstab()函數,它的作用主要是進行分組之后的信息統(tǒng)計,里面會用到聚合函數,默認的是統(tǒng)計行列組合出現的次數,參數如下pandas.crosstab(index,?columns,
????????????????values=None,
????????????????rownames=None,
????????????????colnames=None,
????????????????aggfunc=None,
????????????????margins=False,
????????????????margins_name='All',
????????????????dropna=True,
????????????????normalize=False)
下面小編來解釋一下里面幾個常用的函數
index: 指定了要分組的類目,作為行 columns: 指定了要分組的類目,作為列 rownames/colnames: 行/列的名稱 aggfunc: 指定聚合函數 values: 最終在聚合函數之下,行與列一同計算出來的值 normalize: 標準化統(tǒng)計各行各列的百分比
corss_tab()函數的作用,我們先導入要用到的模塊并且讀取數據集import?pandas?as?pd
df?=?pd.read_excel(
????io="supermarkt_sales.xlsx",
????engine="openpyxl",
????sheet_name="Sales",
????skiprows=3,
????usecols="B:R",
????nrows=1000,
)
output
我們先簡單來看幾個corsstab()函數的例子,代碼如下
pd.crosstab(df['城市'],?df['顧客類型'])
output
顧客類型???會員???普通
省份????????????
上海????124??115
北京????116??127
四川?????26???35
安徽?????28???12
廣東?????30???36
.......
當然我們這里只是指定了一個列,也可以指定多個,代碼如下
pd.crosstab(df['省份'],?[df['顧客類型'],?df["性別"]])
output
顧客類型??會員??????普通????
性別????女性??男性??女性??男性
省份??????????????????
上海????67??57??53??62
北京????53??63??59??68
四川????17???9??16??19
安徽????17??11???9???3
廣東????18??12??15??21
.....
有時候我們想要改變行索引的名稱或者是列方向的名稱,我們則可以這么做
pd.crosstab(df['省份'],?df['顧客類型'],
????????????colnames?=?['顧客的類型'],
????????????rownames?=?['各省份名稱'])
output
顧客的類型??會員???普通
各省份名稱????????????
上海????124??115
北京????116??127
四川?????26???35
安徽?????28???12
廣東?????30???36
crosstab()方法當中的margin參數,如下pd.crosstab(df['省份'],?df['顧客類型'],?margins?=?True)
output
顧客類型???會員???普通???All
省份??????????????????
上海????124??115???239
北京????116??127???243
.....
江蘇?????18???15????33
浙江????119??111???230
黑龍江????14???17????31
All???501??499??1000
你也可以給匯總的那一列重命名,用到的是margins_name參數,如下
pd.crosstab(df['省份'],?df['顧客類型'],
????????????margins?=?True,?margins_name="匯總")
output
顧客類型???會員???普通???匯總
省份??????????????????
上海????124??115???239
北京????116??127???243
.....
江蘇?????18???15????33
浙江????119??111???230
黑龍江????14???17????31
匯總???501??499??1000
normalize參數,如下pd.crosstab(df['省份'],?df['顧客類型'],
????????????normalize=True)
output
顧客類型?????會員?????普通
省份????????????????
上海????0.124??0.115
北京????0.116??0.127
四川????0.026??0.035
安徽????0.028??0.012
廣東????0.030??0.036
.......
要是我們更加傾向于是百分比,并且保留兩位小數,則可以這么來做
pd.crosstab(df['省份'],?df['顧客類型'],
????????????normalize=True).style.format('{:.2%}')
output
顧客類型??會員???普通
省份????????????????
上海?????12.4%???11.5%
北京?????11.6%???12.7%
四川?????26%?????35%
安徽?????28%?????12%
廣東?????30%?????36%
.......
aggfunc參數以及values參數,代碼如下pd.crosstab(df['省份'],?df['顧客類型'],
????????????values?=?df["總收入"],
????????????aggfunc?=?"mean")
output
顧客類型?????????會員?????????普通
省份????????????????????????
上海????15.648738??15.253248
北京????14.771259??14.354390
四川????20.456135??14.019029
安徽????10.175893??11.559917
廣東????14.757083??18.331903
.......
np.sum加總或者是np.median求取平均值。我們還可以指定保留若干位的小數,使用round()函數
df_1?=?pd.crosstab(df['省份'],?df['顧客類型'],
???????????????????values=df["總收入"],
???????????????????aggfunc="mean").round(2)
output
顧客類型?????會員?????普通
省份????????????????
上海????15.65??15.25
北京????14.77??14.35
四川????20.46??14.02
安徽????10.18??11.56
廣東????14.76??18.33
.......
時間類型數據的轉化
df?=?pd.DataFrame({'date':?[1470195805,?1480195805,?1490195805],
???????????????????'value':?[2,?3,?4]})
pd.to_datetime(df['date'],?unit='s')
output
0???2016-08-03?03:43:25
1???2016-11-26?21:30:05
2???2017-03-22?15:16:45
Name:?date,?dtype:?datetime64[ns]
上面的例子是精確到秒,我們也可以精確到天,代碼如下
df?=?pd.DataFrame({'date':?[1470,?1480,?1490],
???????????????????'value':?[2,?3,?4]})
pd.to_datetime(df['date'],?unit='D')
output
0???1974-01-10
1???1974-01-20
2???1974-01-30
Name:?date,?dtype:?datetime64[ns]
pd.to_datetime()方法pd.to_datetime('2022/01/20',?format='%Y/%m/%d')
output
Timestamp('2022-01-20?00:00:00')
亦或是
pd.to_datetime('2022/01/12?11:20:10',
???????????????format='%Y/%m/%d?%H:%M:%S')
output
Timestamp('2022-01-12?11:20:10')
這里著重介紹一下Python當中的時間日期格式化符號
%y 兩位數的年份表示(00-99) %Y 四位數的年份表示(000-9999) %m 表示的是月份(01-12) %d 表示的是一個月當中的一天(0-31) %H 表示的是24小時制的小時數 %I 表示的是12小時制的小時數 %M 表示的是分鐘數 (00-59) %S 表示的是秒數(00-59) %w 表示的是星期數,一周當中的第幾天,從星期天開始算 %W 表示的是一年中的星期數
pd.to_datetime()方法當中的errors參數就可以派上用場,df?=?pd.DataFrame({'date':?['3/10/2000',?'a/11/2000',?'3/12/2000'],
???????????????????'value':?[2,?3,?4]})
#?會報解析錯誤
df['date']?=?pd.to_datetime(df['date'])
output

我們來看一下errors參數的作用,代碼如下
df['date']?=?pd.to_datetime(df['date'],?errors='ignore')
df
output
?date??????value
0?3/10/2000???2
1?a/11/2000???3
2?3/12/2000???4
或者將不準確的值轉換成NaT,代碼如下
df['date']?=?pd.to_datetime(df['date'],?errors='coerce')
df
output
?date???????value
0?2000-03-10???2
1?NaT??????????3
2?2000-03-12???4
數值類型的轉換
DataFrame數據集,如下df?=?pd.DataFrame({
????'string_col':?['1','2','3','4'],
????'int_col':?[1,2,3,4],
????'float_col':?[1.1,1.2,1.3,4.7],
????'mix_col':?['a',?2,?3,?4],
????'missing_col':?[1.0,?2,?3,?np.nan],
????'money_col':?['£1,000.00','£2,400.00','£2,400.00','£2,400.00'],
????'boolean_col':?[True,?False,?True,?True],
????'custom':?['Y',?'Y',?'N',?'N']
??})
output

我們先來查看一下每一列的數據類型
df.dtypes
output
string_col??????object
int_col??????????int64
float_col??????float64
mix_col?????????object
missing_col????float64
money_col???????object
boolean_col???????bool
custom??????????object
dtype:?object
df.info()方法來調用,如下df.info()
output
'pandas.core.frame.DataFrame'>
RangeIndex:?4?entries,?0?to?3
Data?columns?(total?8?columns):
?#???Column???????Non-Null?Count??Dtype??
---??------???????--------------??-----??
?0???string_col???4?non-null??????object?
?1???int_col??????4?non-null??????int64??
?2???float_col????4?non-null??????float64
?3???mix_col??????4?non-null??????object?
?4???missing_col??3?non-null??????float64
?5???money_col????4?non-null??????object?
?6???boolean_col??4?non-null??????bool???
?7???custom???????4?non-null??????object?
dtypes:?bool(1),?float64(2),?int64(1),?object(4)
memory?usage:?356.0+?bytes
我們先來看一下從字符串到整型數據的轉換,代碼如下
df['string_col']?=?df['string_col'].astype('int')
df.dtypes
output
string_col???????int32
int_col??????????int64
float_col??????float64
mix_col?????????object
missing_col????float64
money_col???????object
boolean_col???????bool
custom??????????object
dtype:?object
int32類型,當然我們指定例如astype('int16')、astype('int8')或者是astype('int64'),當我們碰到量級很大的數據集時,會特別的有幫助。那么類似的,我們想要轉換成浮點類型的數據,就可以這么來做
df['string_col']?=?df['string_col'].astype('float')
df.dtypes
output
string_col?????float64
int_col??????????int64
float_col??????float64
mix_col?????????object
missing_col????float64
money_col???????object
boolean_col???????bool
custom??????????object
dtype:?object
astype('float16')、astype('float32')或者是astype('float128')df['mix_col']?=?df['mix_col'].astype('int')
output

pd.to_numeric()方法以及里面的errors參數,代碼如下df['mix_col']?=?pd.to_numeric(df['mix_col'],?errors='coerce')
df.head()
output

我們來看一下各列的數據類型
df.dtypes
output
string_col?????float64
int_col??????????int64
float_col??????float64
mix_col????????float64
missing_col????float64
money_col???????object
boolean_col???????bool
custom??????????object
dtype:?object
float64類型,要是我們想指定轉換成我們想要的類型,例如df['mix_col']?=?pd.to_numeric(df['mix_col'],?errors='coerce').astype('Int64')
df['mix_col'].dtypes
output
Int64Dtype()
replace()方法將這些符號給替換掉,然后再進行數據類型的轉換df['money_replace']?=?df['money_col'].str.replace('£',?'').str.replace(',','')
df['money_replace']?=?pd.to_numeric(df['money_replace'])
df['money_replace']
output
0????1000.0
1????2400.0
2????2400.0
3????2400.0
Name:?money_replace,?dtype:?float64
regex=True的參數,代碼如下df['money_regex']?=?df['money_col'].str.replace('[\£\,]',?'',?regex=True)
df['money_regex']?=?pd.to_numeric(df['money_regex'])
df['money_regex']
astype()方法,對多個列一步到位進行數據類型的轉換,代碼如下df?=?df.astype({
????'string_col':?'float16',
????'int_col':?'float16'
})
或者在第一步數據讀取的時候就率先確定好數據類型,代碼如下
df?=?pd.read_csv(
????'dataset.csv',?
????dtype={
????????'string_col':?'float16',
????????'int_col':?'float16'
????}
)
往期精彩回顧
評論
圖片
表情
