1. 程式人生 > >Pandas資料格式互相轉化[map/filter/re.sub/x.strftime/pd.to_datetime/sort_values/drop_duplicates/apply(str)]

Pandas資料格式互相轉化[map/filter/re.sub/x.strftime/pd.to_datetime/sort_values/drop_duplicates/apply(str)]

導包

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