利用pandas进行数据分析的常用小功能

本文主要介绍了,利用pandas进行数据处理时,经常会用到的一些小技巧

与时间相关

1
2
3
import datetime as dt
from datetime import datetime
import time

时间格式转成字符串

  • 按照给定的格式(%Y%m%d)进行转化
1
2
today = datetime.now()
today
datetime.datetime(2017, 5, 19, 13, 48, 33, 86161)
1
2
date_str = datetime.strftime(today,'%Y%m%d')
date_str
'20170519'

字符串格式转成时间

  • 因为传入的字符串没有时间,所以自动转成了0点,传入是可以给定时间,注意后面的格式保持一致
1
2
date = datetime.strptime('2017-05-15','%Y-%m-%d')
date
datetime.datetime(2017, 5, 15, 0, 0)

浮点数转成时间

  • 先用time.ctime转成时间格式后
1
2
f_time=1.494484e+09
time.ctime(f_time)
'Thu May 11 14:26:40 2017'
  • 再用strptime转成想要的格式
1
datetime.strptime(time.ctime(f_time),"%a %b %d %H:%M:%S %Y")
datetime.datetime(2017, 5, 11, 14, 26, 40)

定义特定的时间

1
2
#指定距离给定日期(today)n天的那个日期,例如n=7
today
datetime.datetime(2017, 5, 19, 13, 48, 33, 86161)
1
today-dt.timedelta(7)
datetime.datetime(2017, 5, 12, 13, 48, 33, 86161)

其他

  • 查询给定日期在今年是第几周,周几
1
today.isocalendar()
(2017, 20, 5)

切割

字符串的切割

  • 用split返回的结果是个list
1
2
test = 'ssssddddsfnnnnnn'
test.split('f')
['ssssdddds', 'nnnnnn']
  • 以下定义了一个按照给定格式切割字符串的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def parse_str(s,symbol):
str1 = None
str2 = None
try:
if pd.isnull(s):
pass
else:
splited = s.split(symbol)
if len(splited)==2:
str1, str2 = splited
else:
str1, str2, *_ = splited #*_表示剩余部分
return str1, str2
except:
return str1, str2
1
2
test = 'ab|cd|ef'
parse_str(test,'|')
('ab', 'cd')
1
2
3
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
1
2
df = DataFrame({'blank':[test]*2})
df
blank
0 ab|cd|ef
1 ab|cd|ef
1
2
df[['str1','str2']] = df['blank'].apply(lambda x:Series(parse_str(x,'|')))
df
blank str1 str2
0 ab|cd|ef ab cd
1 ab|cd|ef ab cd

数据的切割

  • list中的数字切割
1
2
test_data = [1,8,100]
pd.cut(test_data,[0,1,50,np.inf])
[(0, 1], (1, 50], (50, inf]]
Categories (3, object): [(0, 1] < (1, 50] < (50, inf]]
  • 表格中的数字切割
1
2
df = DataFrame({'number':test_data})
df
number
0 1
1 8
2 100
1
2
df['split_number'] = pd.cut(df['number'],[0,1,50,np.inf])
df
number split_number
0 1 (0, 1]
1 8 (1, 50]
2 100 (50, inf]

闭包的形式

  • 对于内侧函数来说,如果某个变量一直是不变的,可以将此变量作为外层的参数,内层函数返回的是结果,外层函数返回的是内层函数,如下:
    • 此函数的用意:表中某列存了IP地址,根据IP地址返回城市
    • 外部有一个df中存放的是某段ip对应的城市信息
1
2
3
4
5
6
7
def outer(df):
def inner(ip):
match=((df['start_ip_integer'].apply(lambda x:x<=ip)) & (df['end_ip_integer'].apply(lambda y:y>=ip)))
return df[match]['city']
return inner
analyse_ip = outer(df)
1
df['city']=df['ip'].apply(analyse_ip)
  • region_df中存放的是经纬度对应的身份、城市,用一下函数返回
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def outer(region_df):
def inner(df):
try:
longitude=df['longitude']
latitude=df['latitude']
matched_df=(region_df[(abs(region_df['longitude']-longitude)<0.01)&(abs(region_df['latitude']-latitude)<0.01)])
if len(matched_df)>0:
return matched_df[['province','city']].iloc[0,:]
else:
return Series([0,0],index = ['province','city'])
except:
print(matched_df)
return inner
analyse_orderid = outer(region_df)
1
df[['orderid_pro','orderid_city']] = df[['longitude','latitude']].apply(analyse_orderid, axis=1)

添加文件

1
2
import sys
sys.path.append('文件地址')

读写文件

1
2
3
4
5
df = pd.read_excel('**.xls',)#读取excel文件
df = pd.read_csv('**.csv',)#读取csv文件
df = pd.read_csv('**.tsv', delimiter='\t')#读取tsv文件
df = pd.read_sql("SELECT * FROM table;",engine)#读取数据库中的数据
df.to_sql('table',engine,flavor='postgres',if_exists='replace',index=False)#将数据存入数据库

按轴转置

  • unstack
1
2
df= DataFrame({'kind1':['a','a','b','b'],'kind2':['k1','k2']*2,'num':[1,2,3,4]}).set_index(['kind1','kind2'])
df
num
kind1 kind2
a k1 1
k2 2
b k1 3
k2 4
1
2
# 直接转置的结果
df.T
kind1 a b
kind2 k1 k2 k1 k2
num 1 2 3 4
1
2
# 用unstack
df.unstack('kind1')
num
kind1 a b
kind2
k1 1 3
k2 2 4

比较两个函数运行的时间,默认运行10000次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from timeit import timeit
def func_compare(func_1,func_2,args=None,kwargs=None,n=10000):
if args is None:
args=[]
if kwargs is None:
kwargs={}
print ("func_1 result:")
print(func_1(*arges,**kwagrs))
print()
print ("func_2 result:")
print(func_2(*arges,**kwagrs))
print()
t1=timeit(lambda:func_1(*arges,**kwagrs),number=n)
t2=timeit(lambda:func_2(*arges,**kwagrs),number=n)
print('time:{t1:0.3f}s vs time:{t2:0.3f}s'.format(t1=t1,t2=t2))

while循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
from pandas import DataFrame
from time import sleep
a=range(1,11)
step = 3
index_strart=0
index_end= index_strart+step
while True:
index_true_end=min(index_end,len(a))
s=list(a[index_strart:index_true_end])
print(s)
if (index_true_end<index_end) or (index_true_end==len(a)):
break
index_strart+=step
index_end+=step
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
[10]

对列数据求和

1
2
df = DataFrame({'kind':['kind1','kind2'],'count':[1,2],'amount':[20,30]})[['kind','count','amount']]
df
kind count amount
0 kind1 1 20
1 kind2 2 30
1
2
df=df.set_index('kind').T
df
kind kind1 kind2
count 1 2
amount 20 30
1
2
df['合计']=df.apply(sum,axis=1)
df
kind kind1 kind2 合计
count 1 2 6
amount 20 30 100
1
2
df=df.T.reset_index()
df
kind count amount
0 kind1 1 20
1 kind2 2 30
2 合计 6 100

隐藏代码的语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')