文章目录
绘图功能
http://c.biancheng.net/pandas/plot.html
ipython的数据展示长度
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
pd.set_option('max_colwidth',200)
读取EXCEL
import xlrd
import os
import pandas as pd
wb = pd.DataFrame(pd.read_excel("file_name.xlsx"))
增删改
创建
1、创建空的DataFrame
column = ['a','b','c']
data = pd.DataFrame(columns=column)
2、利用数组创建
'''创建一个6行4列的数组'''
data = np.random.randn(6,4)
df=pd.DataFrame(data,columns=list('ABCD'),index=[i for i in range(6)])
df
排序
pd.sort_values("xxx",inplace=True)
pd.sort_values(["1","2","3","4"],inplace=True)
处理xlsx文件
import pandas as pd
data = pd.read_excel(io = '1.xlsx')
a = data.values
data = pd.DataFrame(a, columns = [str(i) for i in range(9)])
'''此时转化为了DataFrame格式'''
边删除边遍历csv数据
一边删除一边遍历,需要删除后重新建立索引
wea= pd.read_csv(path)
for i in range(wea.shape[0]):
datee = str(wea.loc[i,'date']) #读取某一列
if():#满足某个条件
wea.drop(wea.index[i],inplace=True)
wea = wea.reset_index(drop = True) #删除后重新建立索引,否则不从0开始
也试过把索引遍历设置变量表示,跟着增加,但不如重置index方法更灵活
loc和iloc(index)
总结两个的用法:
数字代表行(因为也没有行名啊),loc指定列只能用“列名”, iloc指定列只能用数字,列的index;
import pandas as pd
import numpy as np
N = 10
D = 4
X = np.zeros((N, D))
print(X.shape[0])
for i in range(10):
for j in range(4):
X[i][j] = i+j
df = pd.DataFrame(X)
df.columns = ['1','2','3','4']
print(df.head())
#----------------------------loc------------------------------
print(df.loc[4,'1'],type(df.loc[4,'1']))
print('-------第4行--------')
print(df.loc[4])
print('-------第4列--------')
print(df.loc[:,'4'])
print('-------获取多行--------')
print(df.loc[4:7])
print('-------获取多行,某一列-------')
print(df.loc[4:7,'4'])
print('-------获取多行,多列-------')
print(df.loc[4:7,['3','4']])
#----------------------------iloc------------------------------
print(df.iloc[1][2])
print('-------第4行_1--------')
print(df.iloc[4:5],type(df.iloc[4:5]))
print('-------第4行_2--------')
print(df.iloc[4],type(df.iloc[4]))
print('-------第4列_只能通过数字索引第几列--------')
print(df.iloc[:,[3]])
print('-------某行某列一个数字--------')
print(int(df.iloc[1:2,3:4].values),type(df.iloc[1:2,3:4].values),type(int(df.iloc[1:2,3:4].values)))
print('-------多列--------')
print(df.iloc[:,3:4])
print('-------获取多行--------')
print(df.iloc[4:7])
print('-------获取多行,某一列-------')
print(df.iloc[4:7,[3]])
print('-------获取多行,多列-------')
print(df.iloc[4:7,2:4])
输出结果为:(左为loc,右为iloc)
修改
loc , iloc 都可以修改数据
print('------修改数据---------')
print(int(df.iloc[1:2,3:4].values),type(df.iloc[1:2,3:4].values),type(int(df.iloc[1:2,3:4].values)))
df.iloc[1][3] = 4.5
print(np.float64(df.iloc[1:2,3:4].values),type(df.iloc[1:2,3:4].values),type(np.float64(df.iloc[1:2,3:4].values)))
df.iloc[1]['4'] = 4.7
print(np.float64(df.iloc[1:2,3:4].values),type(df.iloc[1:2,3:4].values),type(np.float64(df.iloc[1:2,3:4].values)))
按照条件修改,速度快很多,比apply要快
index_a = df['bb'] == 15
df['rr'] = 0
df.loc[index_a,'rr'] = 1
7000000条数据修改比较速度:
条件筛选:1.5s
apply: 2.3s
插入
1、字典插入一行
row = {'imo':imo,'type_code':type_code,'age':age}
data.loc[total] = row
2、插入一列
pandas.insert(loc, columns, value):
loc要插入的位置、columns列名,value值
'''在第1列后插入一个P列'''
df.insert(1,'P',[0,1,2,3,4,5])
df
插入前后:
去重
df.drop_duplicates(subset=['A','B','C','D'],keep=False)
删除
drop(labels, axis=0, level=None, inplace=False)
lables:要删除数据的标签
axis:0表示删除行,1表示删除列,默认0
inplace:是否在当前df中执行此操作
'''删除第1,3,4行'''
df.drop([1,3,4],axis=0)
'''删除第A,D列'''
df.drop(['A','D'],axis=1)
可以注意到问题:index数值没有改变,而且返回的结果都是对原数据的修改,并没有改变原来结构。然后我们在输出一次df,会发现df和第一张图片是相同的!
如果真的删除的话,需要重新赋值,同时要注意类型,因为有的数据类型进行增删改查等操作之后,类型发生了改变!
'''此时是在原结构上进行的删除!'''
df.drop(['A','D'],axis=1,inplace=True)
但是索引的序列不会有改变,需要重建索引
df.index = [i for i in range(df.shape[0])]
pandas数据处理-聚合-查
http://shzhangji.com/cnblogs/2017/07/23/learn-pandas-from-a-sql-perspective/
先构建
import pandas as pd
import numpy as np
a = [1,2,3,4,5]
b = [11,2,13,4,15]
c = [1,11,3,4,25]
d = np.array([a,b,c])
df = pd.DataFrame(d,columns=['a','b','c','d','e'])
print(df)
axis的理解
axis的重点在于方向,而不是行和列。
当axis=1时,如果是求平均,那么是从左到右横向求平均;如果是拼接,那么也是左右横向拼接;如果是drop,那么也是横向发生变化,体现为列的减少。
考虑了方向,即axis=1为横向,axis=0为纵向,而不是行和列。
合并两个pd格式
pandas.concat(objs, axis=0, join_axes=None, ignore_index=False)
objs:合并对象
axis:合并方式,默认0表示按列合并,1表示按行合并
ignore_index:是否忽略索引
append
合并两个pandas数据,列相同,然后
concat
'''按照行合并'''
df2 = df[['c','d']]
df3 = pd.concat([df,df2], axis = 0, sort=False, ignore_index=True)
print(df3)
df3 = pd.concat([df,df2], axis = 1, sort=False, ignore_index=True)
print(df3)
结果为:
axis = 0
a b c d e
0 1.0 2.0 3 4 5.0
1 11.0 2.0 13 4 15.0
2 1.0 11.0 3 4 25.0
0 NaN NaN 3 4 NaN
1 NaN NaN 13 4 NaN
2 NaN NaN 3 4 NaN
axis = 1
a b c d e c d
0 1 2 3 4 5 3 4
1 11 2 13 4 15 13 4
2 1 11 3 4 25 3 4
merge
'''按照字段左连接合并'''
e = ["2","6","35"]
df2 = pd.DataFrame(np.array([c[:3], e]).T, columns = ['c','E'])
df_merge = pd.merge(df, df2, on = 'c', how = 'left')
print("merge\n", df_merge)
'''left就是按照左边的为准'''
结果为:
a b c d E
0 1 1 1 1 2
1 2 12 12 5 6
2 3 13 3 3 35
3 4 1 1 34 2
4 5 15 25 23 NaN
筛选操作
where
df['c'] = df['c'].apply(int)
condition_1 = df['c'] > 5
condition_2 = df_merge['f'].isnull()
condition_3 = df_merge['f'].notnull()
print("where\n", df_merge[condition_1 & condition_2])
print("where\n", df_merge[condition_1 & ~condition_2])
print("where\n", df_merge[condition_1 & condition_3])
结果:
a b c d E
4 5 15 25 23 NaN
a b c d E
1 2 12 12 5 6
a b c d E
1 2 12 12 5 6
聚合
官方文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html
聚合包含两部分,一是分组字段,二是聚合函数
---------------------------------------------------------多个字段---------------------------------------------------------
temp = df_merge.groupby(['b', 'c']).agg({
'a': np.sum,
'd': np.max
})
print("group\n", temp)
结果:
b c
1 1 14 34
12 12 2 5
13 3 3 3
15 25 5 23
---------------------------------------------------------单个字段---------------------------------------------------------
print(df_merge.groupby('b')['a'].agg(['min', 'max']))
结果:
b min max
1 1 4
12 2 2
13 3 3
15 5 5
---------------------------------------------------------分组迭代---------------------------------------------------------
grouped = df_merge.groupby(['b'])
for index_b, value in grouped:
print("b =",index_b,"--index:",value.index, "\n",value)
print("direct get\n",grouped.get_group("13"))
b = 1
a b c d E
0 1 1 1 1 2
3 4 1 1 34 2
b = 12
a b c d E
1 2 12 12 5 6
b = 13
a b c d E
2 3 13 3 3 35
b = 15
a b c d E
4 5 15 25 23 NaN
直接获取该分组的结果
a b c d E
2 3 13 3 3 35
sort
两种sort。sort_index的作用是啥呢?
1、sort_values
temp_df = df_merge.sort_values(by=['c', 'b'], ascending=False, inplace = False)
print(temp_df)
print(df_merge['b'].dtype)
df_merge['c'] = df_merge['c'].apply(int)
df_merge['b'] = df_merge['b'].apply(int)
temp_df = df_merge.sort_values(by=['c', 'b'], ascending=False, inplace = False)
print(temp_df)
print(df_merge['b'].dtype)
结果:
a b c d E
2 3 13 3 3 35
4 5 15 25 23 NaN
1 2 12 12 5 6
0 1 1 1 1 2
3 4 1 1 34 2
object
a b c d E
4 5 15 25 23 NaN
1 2 12 12 5 6
2 3 13 3 3 35
0 1 1 1 1 2
3 4 1 1 34 2
int64
2、sort_index
temp_df = df_merge.set_index('b').sort_index()
print(temp_df)
join
结果:
rank
结果:
全部代码
pandas-数据挖掘小函数集
apply
def func_1(x):
if(x > 10):
return 1
else:
return 0
def func_2(x):
return x[0] + x[1]
'''单列apply'''
b['ww'] = b['aa'].apply(lambda x: func_1(x))
'''多列apply'''
b['pp'] = b.apply(lambda x: func_2(x))
标准化
from sklearn.preprocessing import StandardScaler
import pandas as pd
import numpy as np
scaler = StandardScaler()
a = [1,2,3,4,5]
b = [11,2,13,4,15]
c = [1,11,3,4,25]
d = np.array([a,b,c])
X = pd.DataFrame(d,columns=['a','b','c','d','e'])
print(X.head())
scaler.fit(X)
print(scaler.transform(X))
输出:
a b c d e
0 1 2 3 4 5
1 11 12 13 14 15
2 10 11 23 4 25
[[-1.4083737 -1.4083737 -1.22474487 -0.70710678 -1.22474487]
[ 0.81537425 0.81537425 0. 1.41421356 0. ]
[ 0.59299945 0.59299945 1.22474487 -0.70710678 1.22474487]]
类型转换
data[["score"]] = data[["score"]].astype(float)
数学计算
1、补位
n = '23'
print(n.zfill(3))
输出为’023’ , 补为3位,前面补0
2、累加平方和
print(type(x))
x = pd.Series(b['aa'].values)
sta = np.cumsum(x ** 2) # 累加的平方和
print(sta)
Categorical
转换数据类型
从csv读取的时间,往往被object默认存放,比较浪费时间,我们首先将object格式转为datetime格式。
pandas速度提升
pandas处理数据实在太慢了,先提一提pandas的速,再去找其他大数据分布式吧
numpy
之前用一步步手写python计算pearson系数,速度无比慢,其实stats已封装好如此经典的计算,直接调用即可。
一些统计的计算可参考官方文档
时间数据类型
dataframe的数据类型都是object,但数据量大了之后发现用dataframe还是很慢。
从csv读出的数据还是object类型,如果将时间格式转为datetiime格式,会提高效率。
df['date_time'] = pd.to_datetime(df['date_time'],format='%d/%m/%y %H:%M')
循环
如果增加一列是依赖另一列的,比如特征有开始和结束,我们想计算花费的时间
我用的比较多的是apply函数。
def func(st, ed):
return ed - st
df['cost'] = df.apply(lambda x: func(x['start], x['end']), axis = 1)
如果你使用.apply()获取10年的小时数据,那么你将需要大约15分钟的处理时间。
如果这个计算只是大型模型的一小部分,那么你真的应该加快速度。这也就是矢量化操作派上用场的地方。
矢量化的操作
.isin()