Pandas資料格式互相轉化[map/filter/re.sub/x.strftime/pd.to_datetime/sort_values/drop_duplicates/apply(str)]
阿新 • • 發佈:2018-12-10
導包
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
建立資料集
datas={'name':['張a亦','張亦','李爾','李爾','趙兆','龔珍c','熊時','王武','王一','王二','李四','趙武','孫泉'], 'phone':['133********']*13, 'date':pd.date_range('20150109',periods=13,freq='D'), 'city':['廣州']*4+['東莞']+['深圳']*2+['惠州']*2+['東莞']+['廣州']*3} df=DataFrame(datas) df
'''測試''' pd.date_range('20150109',periods=13,freq='D') Out: DatetimeIndex(['2015-01-09', '2015-01-10', '2015-01-11', '2015-01-12', '2015-01-13', '2015-01-14', '2015-01-15', '2015-01-16', '2015-01-17', '2015-01-18', '2015-01-19', '2015-01-20', '2015-01-21'], dtype='datetime64[ns]', freq='D')
更換列順序
# 更換列順序
df1=df[['name','phone','date','city']]
df1
檢視資料詳細資訊(在這裡不是純數值沒作用)
df1.describe()
檢視資料格式
# 檢視資料格式,看到data是時間格式可以使用strftime("%Y-%m-%d")
df1.dtypes
Out:
df1.dtypes
name object
phone object
date datetime64[ns]
city object
dtype: object
時間格式轉換str格式:x.strftime("%Y-%m-%d")
# 時間的轉換格式:x.strftime("%Y-%m-%d")
time1=df1.date.map(lambda x: x.strftime('%Y%m%d'))
time1
Out:
0 20150109
1 20150110
2 20150111
3 20150112
4 20150113
5 20150114
6 20150115
7 20150116
8 20150117
9 20150118
10 20150119
11 20150120
12 20150121
df1.date=time1
df1.dtypes
Out:
name object
phone object
date object
city object
dtype: object
1)請將日期(yymmdd)轉換成月份(yymm),並取最大的月份值。
# 檢視date是字串型別
df1.dtypes
Out:
name object
phone object
date object
city object
dtype: object
# string類轉化格式只需要改變字串拼接即可
time_zhuan=df1.date.map(lambda x: x[0:4]+x[4:6])
time_zhuan
Out:
0 201501
1 201501
2 201501
3 201501
4 201501
5 201501
6 201501
7 201501
8 201501
9 201501
10 201501
11 201501
12 201501
Name: date, dtype: object
str轉換成時間格式:pd.to_datetime()
# string類轉化格式,使用pd.to_datetime(df1.date)轉化成時間格式即可為xxxx-xx-xx
data_time=pd.to_datetime(df1.date)
data_time
Out:
0 2015-01-09
1 2015-01-10
2 2015-01-11
3 2015-01-12
4 2015-01-13
5 2015-01-14
6 2015-01-15
7 2015-01-16
8 2015-01-17
9 2015-01-18
10 2015-01-19
11 2015-01-20
12 2015-01-21
Name: date, dtype: datetime64[ns]
# 將轉化好的時間型別賦值至表格中
df1.date=time_zhuan
df1.dtypes
Out:
name object
phone object
date object
city object
dtype: object
取出最大的月份值:使用map遍歷所有值取月份的值,並進行.max()
df1['date'][2]='201510'
df1['date'][5]='201509'
df1['date'][10]='201510'
df1['date'][3]='201502'
df1['date'][6]='201511'
df1['date'][0]='201506'
df1['date'][1]='201508'
# 遍歷date資料,擷取月份部分,使用聚合max()求出最大值
month=(df1.date.map(lambda x : x[4:])).max()
# month.max()
month
2)統計客戶城市的分佈情況,城市是廣州的客戶佔總客戶的百分比
(df1.city=='廣州').sum()/df1.city.size
Out:
0.5384615384615384
3)姓名的正確格式為中文,去掉姓名欄位的英文字元存入資料集A中
導包
import re
檢視
df1.name
Out:
0 張a亦
1 張亦
2 李爾
3 李爾
4 趙兆
5 龔珍c
6 熊時
7 王武
8 王一
9 王二
10 李四
11 趙武
12 孫泉
Name: name, dtype: object
測試filter
# 篩選出含有A-z的字元的名字(測試filter用)
list(filter(lambda x:re.findall('[A-Za-z]',x),df1.name))
Out:
['張a亦', '龔珍c']
使用 正則: re.sub('過濾規則','要替換成的規則',str)
# 使用 正則的 re.sub('過濾規則','要替換成的規則',str)
new_name=df1.name.map(lambda x: re.sub('[A-Za-z]','',x))
new_name
Out:
0 張亦
1 張亦
2 李爾
3 李爾
4 趙兆
5 龔珍
6 熊時
7 王武
8 王一
9 王二
10 李四
11 趙武
12 孫泉
Name: name, dtype: object
# 將變換的資料替換至表格中
df1.name=new_name
df1
存入資料集A中
A=df1.copy()
A
3)取出姓氏為“李”的客戶記錄,存入資料集B中
檢視
df1.name
Out:
0 張亦
1 張亦
2 李爾
3 李爾
4 趙兆
5 龔珍
6 熊時
7 王武
8 王一
9 王二
10 李四
11 趙武
12 孫泉
Name: name, dtype: object
篩選
# 篩選出 “李” 姓氏的客戶
li_list=list(filter(lambda x:re.findall('李.*',x),df1.name ))
li_list
['李爾', '李爾', '李四']
'''將名字列設定為列索引'''
df1.set_index(df1.name,inplace=True)
df1.index
Out:
Index(['張亦', '張亦', '李爾', '李爾', '趙兆', '龔珍', '熊時', '王武', '王一', '王二', '李四', '趙武',
'孫泉'],
dtype='object', name='name')
# 將名字列刪除
df1.drop('name',axis=1,inplace=True)
# 過濾掉重複的名字
li_Seri=pd.Series(li_list).unique()
li_Seri
Out:
array(['李爾', '李四'], dtype=object)
篩選後的資料存入表B
# 使用篩選出的過濾後的名字來篩選整個欄位的資訊
B=df1.loc[li_Seri]
B
資料集 Table2 有變數:姓名、年齡,如下:Tb2
data2={'name':['張亦','李爾','趙兆','龔珍','熊時','王武','王一','王二','李四','趙武','孫泉'],
'age':[30,26,'.',70,20,19,45,'.',47,32,50],}
Tb2=DataFrame(data2)
Tb2
Tb2=Tb2[['name','age']]
Tb2
合併資料集A
C=pd.merge(A,Tb2)
C
C_1=C.copy()
C_1
給資料集排序sort_values(ascending=False:按降序排序,即日期小的排在後面)
C_1=C_1.sort_values(by='date',ascending=False)
C_1
# 保留後一項,刪除前一項重複資料
C_1.duplicated('name', keep='last')
Out:
6 False
2 True
10 False
5 False
1 True
0 False
3 False
4 False
7 False
8 False
9 False
11 False
12 False
dtype: bool
# 保留第一項,刪除後一項重複資料
C_1.duplicated('name', keep='first')
Out:
6 False
2 False
10 False
5 False
1 False
0 True
3 True
4 False
7 False
8 False
9 False
11 False
12 False
dtype: bool
C_1.drop_duplicates('name', keep='first',inplace=True)
C_1
統一轉化為string型別:apply(str)
# 統一轉化為string型別
C_1.age=C_1.age.apply(str)
C_1.age
OUt:
6 20
2 26
10 47
1 30
5 70
4 .
7 19
8 45
9 .
11 32
12 50
Name: age, dtype: object
求最大年齡
max(C_1.age)
Out: '70'
拓展:reduce(lambda a,b:int(a)+int(b),C_1.age)
from functools import reduce
# 如果列中沒有缺失值,可以使用該方法累加
reduce(lambda a,b:int(a)+int(b),C_1.age)
求平均年齡
sum=0
for i in C_1.age:
if i !='.':
# print(i)
sum+=int(i)
print(sum/C_1.age.size)
Out:
30.818181818181817
# 顯示2位小數
a=30.818181818181817
print('%.2f'%a)
Out : 30.82
替換'.'為np.nan
① 使用 replace
C_1.age.replace(to_replace='.',value=np.nan,inplace=True)
C_1
② 使用 map
C_1.age=C_1.age.map(lambda x: np.nan if x =='.' else x)
C_1.age
Out:
6 20
2 26
10 47
1 30
5 70
4 NaN
7 19
8 45
9 NaN
11 32
12 50
Name: age, dtype: object
統計缺失值
'''檢視是否有缺失值,有則為True'''
C_1.age.isnull().any()
Out: True
# 統計數量
C_1.age.isnull().sum()
Out:2
空值處理:fillna/bfill/ffill/dropna
填充缺失值 or 刪除缺失值
'''引數:value=None, method=None, axis=None, inplace=False, limit=None'''
C_1.age.fillna(value=0)
Out:
6 20
2 26
10 47
5 70
1 30
4 0
7 19
8 45
9 0
11 32
12 50
Name: age, dtype: object
'''向前填充,引數:axis=None, inplace=False, limit=None, downcast=None'''
C_1.age.bfill()
Out:
6 20
2 26
10 47
5 70
1 30
4 19
7 19
8 45
9 32
11 32
12 50
Name: age, dtype: object
'''向後填充,引數:axis=None, inplace=False, limit=None, downcast=None'''
C_1.age.ffill()
Out:
6 20
2 26
10 47
5 70
1 30
4 30
7 19
8 45
9 45
11 32
12 50
Name: age, dtype: object
'''預設刪除行記錄,引數:axis=0, inplace=False, **kwargs'''
C_1.age.dropna()
Out:
6 20
2 26
10 47
5 70
1 30
7 19
8 45
11 32
12 50
Name: age, dtype: object