pandas 细节总结
- 数据处理总结
- 其他细节
- 1、pandas option设置
- 2、pandas统计
- 3、多列排序 data.sort_values()
- 4、去重复
- 5、基于其他列创建一个新列
- 6、删除某列 data.drop()
- 7、Series替换元素 Seriesdata.replace()
- 8、重命名索引名或列名
- 9、数据分箱 pd.cut(data,bins)
- 10、数据分组 df.group()
- 11、DataFrame切片
- 12、series切片
- 13、布尔索引
- 14、根据列标签获得列
- 15、统计计数
- 15、索引操作
- 16、时间索引
- 17、python mysql(sqlalchemy+pandas)
- 18、 强制类型转换
- 19、DataFrame运算——累计统计函数
- 20、pandas 索引用法
- 21、lambda函数和if判断使用
- 22、DataFrame.apply与GroupBy.apply比较
- 23、data.drop_duplicates删除重复数据,
- 24、drop函数删除某列某行 pd.DataFrame.drop()
- 25、数据关联merge
- 26、数据类型转换 DataFrame.astype() 方法
- 27、清理无效数据 df.dropna() df[df.notnull()]
- 28、给DataFrame的列命名或重命名
- 29、DataFrame对象groupby.agg方法
数据处理总结
采样
SMOTE
# 过采样
sm = SMOTE() # lets reduce the imbalance
X_train = train_fp[predictors2]
print(predictors2)
y_train = train_fp[target]
counter = Counter(y_train)
print(counter)
X_res, y_res = sm.fit_sample(X_train, y_train)
counter = Counter(y_res)
print(counter)
train = pd.concat([X_res,y_res],axis=1)
train.info()
降采样
def lower_sample_data(df, labelname, percent=1):
'''
percent:多数类别下采样的数量相对于少数类别样本数量的比例
'''
data1 = df[df[labelname] == 1] # 将少数类别的样本放在data1
data0 = df[df[labelname] == 0] # 将多数类别的样本放在data0
index = np.random.randint(
len(data0), size=percent * (len(data1))) # 随机给定下采样取出样本的序号
lower_data0 = data0.iloc[list(index)] # 下采样
return(pd.concat([lower_data0, data1]))
print(train_data["'Purchase or not'"].value_counts())
train_data4 = lower_sample_data(train_data, "'Purchase or not'", percent=1)
print(train_data4["'Purchase or not'"].value_counts())
上采样
数据整合与拆分
整合 pd.concat()
train_data = pd.read_csv(‘train.csv’)
test_data = pd.read_csv(‘test.csv’)
total_data = pd.concat([train_data, test_data], axis=0)
total_data.info()
拆分
数据格式转换
#格式转换
train_in = train_in.apply(pd.to_numeric, errors='ignore') # 自动转换格式
test_in = test_in.apply(pd.to_numeric, errors='ignore') # 自动转换格式
# train_in.hist(bins=60,figsize = (12,12))
字符串处理
train_0['area1'] = train_0['area'].apply(lambda x: np.nan if len(str(x))<3 else int((str(x))[0]) )
train_0['area2'] = train_0['area'].apply(lambda x: np.nan if len(str(x))<3 else int((str(x))[
数据筛选
cdma = pd.read_csv('cdma.xls', encoding='gbk', sep='\t')
print(cdma.shape)
cdma = cdma[(cdma['销售区局'] == '浦东电信局') & (cdma['渠道管理细分'].isin(['专营渠道', '中小渠道', '开放渠道']))]
print(cdma.shape)
# cdma = cdma[~cdma['发展部门名称'].str.contains('千秋')]
# print(cdma.shape)
dataframe.where()
df.B.div(df.A.where(df.A != 0, np.nan))
train_1['ck-saveavg_cal'] = train_1['ck-saveall'].div(train_1['ck-savetime'].where(train_1['ck-savetime']!=0,np.nan))
train_1['ck-drawavg_cal'] = train_1['ck-drawall'].div(train_1['ck-drawtime'].where(train_1['ck-drawtime']!=0,np.nan))
数据关联
match_table = pd.read_excel('数据说明与匹配公式.xlsx', sheet_name='部门匹配表')
new_cdma = cdma.merge(match_table, how='left', on=['发展部门名称', '渠道管理细分'])
new_cdma = new_cdma[new_cdma['渠道管理细分'] == '专营渠道']
new_cdma[['统计日期', '订单号', '所属部门', '所属代理商', '所属分局', '渠道经理']].head()
数据透视表 df.pivot_table()
cdma_pivot = new_cdma.pivot_table(index='所属代理商', values='订单号', columns='所属分局', aggfunc='count', fill_value=0, margins=True, margins_name='合计')
cdma_pivot
数据排序 df.sort_values()
cdma_pivot = new_cdma.pivot_table(index='所属代理商', values='订单号', columns='所属分局', aggfunc='count', fill_value=0, margins=True, margins_name='合计')
cdma_pivot
数据替换 df.repalce()
train_data = train_data.replace('?', np.nan) #精准匹配
train_data.head(10)
train_data2 = train_data.replace('Tai', 'Cy', regex=True) #模糊匹配
train_data2.head(10)
数据删除 df.dropna()
print(train_data.shape)
train_data3 = train_data.dropna(subset=['gender', 'age'])
print(train_data3.shape)
数值数据离散化(cut/qcut)
分箱注意点:可以利用分箱中的lable参数,设置分类的标签值,例如[1,2,3,4,5,6] (分成6个箱情况 )
# age 分箱
age_range = [18,25,35,45,55,65,75,100]
train_0['age_cut1'] = pd.cut(train_0['age'], age_range, include_lowest=True, right=False,labels=[1,2,3,4,5,6,7])
train_0['age_cut1'].value_counts().sort_index()
train_0.info()
#----------------------------------------------------------------------------------------------------
age_range = [18,25,35,45,55,65,75,100]
test_0['age_cut1'] = pd.cut(test_0['age'], age_range, include_lowest=True, right=False,labels=[1,2,3,4,5,6,7])
test_0['age_cut1'].value_counts().sort_index()
# test_0.info()
人工分离法
age_range = list(range(0,111,10))
train_data5['age_cut1'] = pd.cut(train_data5['age'], age_range, include_lowest=True, right=False)
train_data5['age_cut1'].value_counts().sort_index()
等宽装箱法
train_data5['age_cut2'] = pd.cut(train_data5['age'], bins=10, include_lowest=True, right=False, precision=0)
train_data5['age_cut2'].value_counts().sort_index()
等深装箱法
train_data5['age_cut3'] = pd.qcut(train_data5['age'], 10, precision=1)
train_data5['age_cut3'].value_counts().sort_index()
类别变量编码
# 分类变量处理,onehot编码,适应有缺失值的情况
# area
dum_area = pd.get_dummies(train_0['User area'], prefix='area')
dum_area.head()
# gender
dum_gender = pd.get_dummies(train_0['gender'], prefix='gender')
dum_gender.head()
数据泛化[数据一般化](map)
print(cdma['发展渠道小类'].value_counts())
qd_map = {'自营营业厅': '自营渠道', '专营店': '专营渠道', '合作营业厅': '专营渠道', '核心渠道专区专柜':'专营渠道', '天翼小店':'中小渠道',
'外包营业厅':'专营渠道', '全国连锁卖场': '开放渠道', '全网通(专营)':'专营渠道', '商圈店':'专营渠道', '天翼合作店':'中小渠道', '终端零售店(开放)':'中小渠道'}
cdma_2 = cdma.copy()
cdma_2['渠道统计归类'] = cdma_2['发展渠道小类'].map(qd_map)
print(cdma_2['渠道统计归类'].value_counts())
数据标准化
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
mm_scaler = MinMaxScaler()
ss_scaler = StandardScaler()
print(train_data9['age'].head())
train_data9['age'] = mm_scaler.fit_transform(train_data9[['age']])
print(train_data9['age'].head())
print('-------------------------------------------------')
print(train_data9['MonthlyIncome'].head())
train_data9['MonthlyIncome'] = ss_scaler.fit_transform(train_data9[['MonthlyIncome']])
print(train_data9['MonthlyIncome'].head())
缺失值处理
查看缺失比例
train_data5 = pd.read_csv('cs-training.csv')
per_columns = set(train_data5.columns) - set(['CustomerID', 'SeriousDlqin2yrs'])
for column in per_columns:
temp_mean = train_data5[column].mean() #如果是中位数的话是median,众数的话是mode
train_data5[column] = train_data5[column].fillna(temp_mean)
train_data5.describe()
数据异常处理
异常值处理
# 异常值处理
# 异常值填充nan
def cap_nan(x, quantile=[0.25, 0.75]):
"""盖帽法处理异常值
Args:
x:pd.Series列,连续变量
quantile:指定盖帽法的上下分位数范围
"""
# 生成分位数
Q25, Q75=x.quantile(quantile).values.tolist()
low = Q25 - 1.5*(Q75 - Q25)
up = Q75 + 1.5*(Q75 - Q25)
# 替换异常值为指定的分位数
if low > x.min():
x = x.copy()
x.loc[x<low] = np.nan
if up < x.max():
x = x.copy()
x.loc[x>up] = np.nan
return(x)
# 异常值填充最大最小值
def cap_low_up(x, quantile=[0.25, 0.75]):
"""盖帽法处理异常值
Args:
x:pd.Series列,连续变量
quantile:指定盖帽法的上下分位数范围
"""
# 生成分位数
Q25, Q75=x.quantile(quantile).values.tolist()
low = Q25 - 1.5*(Q75 - Q25)
up = Q75 + 1.5*(Q75 - Q25)
# 替换异常值为指定的分位数
if low > x.min():
x = x.copy()
x.loc[x<low] = low
if up < x.max():
x = x.copy()
x.loc[x>up] = up
return(x)
train_14 = train_0.copy()
train_14[predictors] = train_14[predictors].apply(cap_nan)
四分位法 np.where(condition,df1,df2)
'''
Low = Ser.quantile(0.25)-1.5*(Ser.quantile(0.75)-Ser.quantile(0.25))
Up = Ser.quantile(0.75)+1.5*(Ser.quantile(0.75)-Ser.quantile(0.25))
'''
# 选取测试集数据95%、5%分位数作为临界点
Ser_Low = data_train.iloc[:,1:11].quantile(0.05)
Ser_Up = data_train.iloc[:,1:11].quantile(0.95)
data_train.iloc[:,1:11] =np.where(data_train.iloc[:,1:11] >= Ser_Up,Ser_Up,\
np.where(data_train.iloc[:,1:11]<= Ser_Low,Ser_Low,data_train.iloc[:,1:11].copy()))
# data_train.to_csv('异常值处理.csv')
data_test.iloc[:,1:11] =np.where(data_test.iloc[:,1:11] >= Ser_Up,Ser_Up,\
np.where(data_test.iloc[:,1:11]<= Ser_Low,Ser_Low,data_test.iloc[:,1:11].copy()))
四分位法
def cap(x, quantile=[0.05, 0.95]):
"""盖帽法处理异常值
Args:
x:pd.Series列,连续变量
quantile:指定盖帽法的上下分位数范围
"""
# 生成分位数
Q05, Q95=x.quantile(quantile).values.tolist()
# 替换异常值为指定的分位数
if Q05 > x.min():
x = x.copy()
x.loc[x<Q05] = Q05
if Q95 < x.max():
x = x.copy()
x.loc[x>Q95] = Q95
return(x)
train_data6 = train_data5[per_columns]
train_data6 = train_data6.apply(cap)
train_data7 = pd.concat([train_data5[['CustomerID', 'SeriousDlqin2yrs']], train_data6], axis=1)
train_data7 = train_data7[train_data5.columns]
train_data7.describe()
3Sigma法
def cap_mean(x):
"""盖帽法处理异常值
Args:
x:pd.Series列,连续变量
"""
# 生成平均值和标准差的上下界限
x_up = x.mean() + 3*x.std()
x_down = x.mean() - 3*x.std()
# 替换异常值
if x_down > x.min():
x = x.copy()
x.loc[x<x_down] = x_down
if x_up < x.max():
x = x.copy()
x.loc[x>x_up] = x_up
return(x)
train_data8 = train_data5[per_columns]
train_data8 = train_data8.apply(cap_mean)
train_data9 = pd.concat([train_data5[['CustomerID', 'SeriousDlqin2yrs']], train_data8], axis=1)
train_data9 = train_data9[train_data5.columns]
train_data9.describe()
连续指派
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
cdma_2['渠道统计归类'] = le.fit_transform(cdma_2[['渠道统计归类']])
cdma_2['渠道统计归类'].value_counts()
数据格式转换
场景:
-
数据集中有缺失值,dataframe列对象为object。
-
object不支持dataframe.hist()作图。自动转换格式后,将object格式自动切换为int或者float格式
-
object对象不支持describe()描述四分位数、分位数、平均值等
train = train.apply(pd.to_numeric, errors='ignore') # 自动转换格式
训练模型前检查数据中是否有缺失值
其他细节
1、pandas option设置
import pandas as pd
pd.set_option("display.max_rows",1000)
pd.set_option("display.max_columns",20)
pd.set_option('precision',7)
pd.set_option('large_repr', 'truncate')
1、pd.set_option('expand_frame_repr', False)
True就是可以换行显示。设置成False的时候不允许换行
2、pd.set_option('display.max_rows', 10)
pd.set_option('display.max_columns', 10)
显示的最大行数和列数,如果超额就显示省略号,这个指的是多少个dataFrame的列。如果比较多又不允许换行,就会显得很乱。
3、pd.set_option('precision', 5)
显示小数点后的位数
4、pd.set_option('large_repr', A)
truncate表示截断,info表示查看信息,一般选truncate
5、pd.set_option('max_colwidth', 5)
列长度
6、pd.set_option('chop_threshold', 0.5)
绝对值小于0.5的显示0.0
7、pd.set_option('colheader_justify', 'left')
显示居中还是左边,
8、pd.set_option('display.width', 200)
横向最多显示多少个字符, 一般80不适合横向的屏幕,平时多用200.
2、pandas统计
快速统计信息和数据类型 df.describe().T 、 df.info()
data.describe().T
data.info()
df.info() shows data types, number of rows and columns, and memory usage of your dataframe
import pandas as pd
data = pd.DataFrame({'group': ['a', 'a', 'a', 'b','b', 'b', 'c', 'c','c'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
data.describe().T
data.info()
'''
<class 'pandas.core.frame.DataFrame'>
Int64Index: 9 entries, 0 to 8
Data columns (total 2 columns):
group 9 non-null object
ounces 9 non-null float64
dtypes: float64(1), object(1)
memory usage: 216.0+ bytes
'''
重复值
data.drop_duplicates(subset='列名',keep='first',inplace=True)
缺失值
DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)
功能:使用指定的方法填充NA / NaN值
参数:value : 变量, 字典, Series, or DataFrame
用于填充缺失值(例如0),或者指定为每个索引(对于Series)或列(对于DataFrame)使用哪个字典/Serise/DataFrame的值。(不在字典/Series/DataFrame中的值不会被填充)这个值不能是一个列表。
method : {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, 默认值 None ; 在Series中使用方法填充空白(‘backfill’, ‘bfill’向前填充,‘pad’, ‘ffill’向后填充)
axis : {0 or ‘index’, 1 or ‘columns’}
inplace : boolean, 默认值 False。如果为Ture,在原地填满。注意:这将修改次对象上的任何其他视图(例如,DataFrame中的列的无复制贴片)
limit : int, 默认值 None; 如果指定了方法,则这是连续的NaN值的前向/后向填充的最大数量。 换句话说,如果连续NaN数量超过这个数字,它将只被部分填充。 如果未指定方法,则这是沿着整个轴的最大数量,其中NaN将被填充。 如果不是无,则必须大于0。
downcast : dict, 默认是 None; 如果可能的话,把 item->dtype 的字典将尝试向下转换为适当的相等类型的字符串(例如,如果可能的话,从float64到int64)
data_train = data_train.fillna(data_train.mean())
data_train = data_test.fillna(data_train.mean())
# print(data_train.isnull().sum())
'''
data.fillna(method='bfill') ### 用相邻前面(before)特征填充后面空值
data.fillna(method='bfill') ### 用相邻后面(back)特征填充前面空值
data.fillna(data.mean()) ### 用每列特征的均值填充缺失数据
data.fillna(data.median()) ### 用每列特征的中位数填充缺失数据
3、多列排序 data.sort_values()
data.sort_values()
原位修改data:
data.sort_values(by=['group','ounces'], ascending=[False, True], inplace=True)
或者
data = data.sort_values(by=['group','ounces'], ascending=[False, True])
inplace参数表示原位修改,默认是False。
索引值排序 data.sort_index()
df.sort_index(axis=1,ascending=False) axis=1行上的操作,index行上是索引名或者列名,按照列名排序(小写的比大写的字母大)
)
sort_index可以以轴的标签进行排序,axis是指用于排序的轴,可选的值可以使0或1,默认是0,即行标签(Y轴),1按照列标签排序(X轴)
ascending=True表示降序排序。
4、去重复
4.1、全部列去重复 data.drop_duplicates()
data.drop_duplicates() # by default, duplicate is defined by all columns
4.2、某一列去重复 data.drop_duplicates(subset = ‘列标签’)
data.drop_duplicates(subset='k1')
5、基于其他列创建一个新列
M1:添加修改列:df.assign()默认修改元数据
df.assign(** kwargs)
#创建或修改列并添加到原数据中,默认修改,没有inplace参数;
参数: #kwargs:关键字值对(列名,【函数,系列,标量或数组】) 返回:df
s=pd.Series([11,12,13],name='S')
data=np.arange(21,24)
df=pd.DataFrame({'A':[31,32,33],'B':[41,42,43]})
fun=lambda x:x.A+x.B
df.assign(C=fun,D=df.A+df.B,E=s,F=data)#增加新列
A B C D E F
0 31 41 72 72 11 21
1 32 42 74 74 12 22
2 33 43 76 76 13 23
df=pd.DataFrame({'A':[31,32,33],'B':[41,42,43]})
df.assign(B=df.A, C=lambda x:x['A']+ x['B'])# 关键字参数相互依赖位置Python3.6以上版本
A B C
0 31 31 62
1 32 32 64
2 33 33 66
=======================================
#所有Python版本兼容的代码,请将赋值分成两部分
df = pd.DataFrame({"A": [1, 1, 1]})
(df.assign(A=lambda x: x['A'] + 1)
.assign(B=lambda x: x['A'] + 2))
A B
0 2 4
1 2 4
2 2 4
M2:map + dict
seriesdata.map(dict_)
import pandas as pd
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami','corned beef', 'Bacon', 'pastrami', 'honey ham','nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
'bacon': 'pig',
'pulled pork': 'pig',
'pastrami': 'cow',
'corned beef': 'cow',
'honey ham': 'pig',
'nova lox': 'salmon'
}
def meat2animal(series):
if series["food"]=='bacon':
return 'pig'
elif series["food"]=='Bacon':
return 'pig'
elif series["food"]=='pulled pork':
return 'pig'
elif series["food"]=='pastrami':
return 'cow'
elif series["food"]=='corned beef':
return 'cow'
elif series["food"]=='honey ham':
return 'pig'
else:
return 'salmon'
data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
M3、Seriesdata.map(func_)
data['animal2'] = data.apply(meat2animal,axis='columns')
6、删除某列 data.drop()
df.drop('列标签',axis='columns',inplace=True)
7、Series替换元素 Seriesdata.replace()
替换一个值,参数为数值:
data.replace(-999, np.nan, inplace=True)
替换多个值,参数为列表:
data.replace([-999, -1000], np.nan, inplace=True)
在pandas中空值用np.nan表示
import pandas as pd
data = pd.Series([1., -999., 2., -999., -1000., 3.])
data.replace(-999, np.nan, inplace=True)
#If you want to replace multiple values at once, you instead pass a list then the substitute value
data.replace([-999, -1000], np.nan, inplace=True)
8、重命名索引名或列名
在原索引上修改 data.index.map()
data.index = data.index.map(str.upper)
data.index.map(str.upper)
#Index(['OHIO', 'COLORADO', 'NEW YORK'], dtype='object') index对象向
data.index = data.index.map(str.upper)
整体改变索引、列名称 data.rename()
inplace参数表示是否在原位上修改,index,columns输入为内置函数
data.rename(index=str.title, columns=str.upper, inplace=True)
原位修改等同于下面两行代码:
data = data.rename(index=str.title, columns=str.upper)
部分改变索引名 data.rename()
inplace参数表示是否在原位上修改,index,columns输入为字典
data.rename(index={'Ohio': 'INDIANA'},columns={'three': 'peekaboo'},inplace=True)
9、数据分箱 pd.cut(data,bins)
pd.cut(cats,bins)
默认左开右闭
pd.cut(cats,bins,right=False)
设置 左闭右开
cats.categories
pd.value_counts(cats)
设置分类对象索引名称,lables参数输入列表,默认是分箱结果:
pd.cut(ages, bins, labels=group_names)
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
cats
'''
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
'''
cats.categories
'''
IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]]
closed='right',
dtype='interval[int64]')
'''
pd.value_counts(cats)
'''
(18, 25] 5
(35, 60] 3
(25, 35] 3
(60, 100] 1
dtype: int64
'''
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)
pd.cut(ages, bins, labels=group_names).categories
'''
Index(['Youth', 'YoungAdult', 'MiddleAged', 'Senior'], dtype='object')
'''
pd.value_counts(pd.cut(ages, bins, labels=group_names))
'''
Youth 5
MiddleAged 3
YoungAdult 3
Senior 1
dtype: int64
'''
10、数据分组 df.group()
data.grouped()
grouped = df['data1'].groupby(df['key1'])
分类对象:<pandas.core.groupby.groupby.SeriesGroupBy object at 0x00000197FD92BEB8>
data.value_counts()
data.pivot_table()
11、DataFrame切片
3种方法切片,
df切片可以写很长df[逻辑条件][列标签]
df[df.one>1][['one','two']] ; df[df.one>1][['one','two']].max()
M1: df.loc()方法(location)标签
loc方法只支持标签,不支持数字。只能给index或者列名称。
df.loc[行标签,列标签]
df.loc[:,‘列名’] :表示所有,’,'前面表示行,后面表示列
M2: df.iloc()方法(int location)位置
给的不是标签是数字。df.iloc[行位置,列位置]
选择行数据 df.iloc[[1,2],:]2、3行。 df.iloc[0:2,:]1、2行。
import pandas as pd
data = pd.DataFrame([[1,2,3,4,5,6],[11,12,13,14,15,16]])
print(data.iloc[:,[*range(1,5)]])
M3:df.ix()混合型方法 标签+位置(较M1、2推荐M3)
df.ix 既可以给数字也可以给标签,也可以混合。
df.ix[1,1] 第2行第2列
df.ix[‘a’:‘b’]标签从‘a’到‘b’在ix,包括了‘a’和‘b’
M4:df[逻辑条件]
两种中方法,第一种方法将条件转换为0和1,满足至少……(尤其是部分条件满足);第二种方法是使用逻辑条件
i、(逻辑条件)*1将逻辑条件转换为0和1
(df.ones>1)*1
返回数字
df[(df.one >1)*1+(df.two>1)*1 ==2]
#两个条件都满足,和为1,满足一个就是1,将返回值放到df中
5个条件只要满足3个就可以,选择第一种方法。
ii、逻辑条件使用& | df[()&()]
df[df.one>1]
df[(df.one >1)&(df.two>2)] #多个条件逻辑组合
并列条件注意df.列名,列名不能和df关键字数重名。比如说df.diff是df下面的一个函数,如果列名也是diff,选择数据不能被选择到。可以用df[‘diff’]这时候将diff认作是列名,不是关键字。
M5:使用索引切片获取前n行 df[1:3]
df[0:3] # get first 3 rows of the dataframe
df['20130102':'20130104'] # get rows by index range
df切片可以写很长
df[逻辑条件][列标签]
df[df.one>1][[‘one’,‘two’]]
df[df.one>1][[‘one’,‘two’]].max()
12、series切片
索引列表 Seriesdata[[‘A’,‘B’,‘C’]]
population = pd.Series({'Germany': 81.3, 'Belgium': 11.3, 'France': 64.3, 'United Kingdom': 64.9, 'Netherlands': 16.9})
population['France']
population['Belgium':'Germany'] #列标签包前包后,数字包前不包后
#布尔列表或者列表
population[population > 20]
population[['France', 'Netherlands']]
Series元素操作
population / 100
population.mean()
索引相同可以相加
s1 = population[['Belgium', 'France']]
s2 = population[['France', 'Germany']]
s1 + s2
13、布尔索引
|
| for or, &
for and,~
for not
df[bool_condition]
df[df['A']>0]
df[df.A>0]
df[~bool_condition]
df2[~df2['E'].isin(['two','four'])]
df[sdata.isin([‘str1’,‘str2’])]
df2[df2['E'].isin(['two','four'])]
列E为 two或者 four的所有行,isin后面接列表。
在时间数据处理时,可以用isin找出工作日时间。
df[sdata.str.contains(‘str1|str2’)]
字符串匹配df2[df2.E.str.contains("tw|ou")]
df.query(‘A>0’)
很少用,等价于df[df.A>0],A为列标签。
14、根据列标签获得列
df.filter(like='data')
模糊匹配,列名like’data’,例如data1等。
适用于数据集列很多,且列名定义有规律的数据集。
15、统计计数
M1: sdata_value_counts() series函数
data.A.value_counts()
输出:
b 3
c 3
a 3
M2: count() 聚合函数
data.A.value_counts()
等价于
data.A.groupby(data.A).count()
输出:
A
b 3
c 3
a 3
M3: Pivot table
data.pivot_table(values='A',index='A',aggfunc='count')
import pandas as pd
data = pd.DataFrame({'group': ['a', 'a', 'a', 'b','b', 'b', 'c', 'c','c'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
data
'''
group ounces
0 a 4.0
1 a 3.0
2 a 12.0
3 b 6.0
4 b 7.5
5 b 8.0
6 c 3.0
7 c 5.0
8 c 6.0
'''
data.pivot_table(values='ounces',index='group',aggfunc=np.mean)
'''
group
a 6.333333
b 7.166667
c 4.666667
Name: ounces, dtype: float64
'''
data.pivot_table(values='ounces',index='group',aggfunc='count').cumsum()
'''
group
a 3
b 6
c 9
Name: ounces, dtype: int64
'''
累积求和 cumsum()
data.A.value_counts().cumsum()
15、索引操作
16、时间索引
字符串索引转DataTime格式索引
下面的时间索引的操作基于index为时间索引,datetime格式。
如果是字符串,需要转换成datetime格式,推荐pd.to_datetime
str = ['2010-04-01','2012-02-03']
a1 = pd.to_datetime(str)
a1 #DatetimeIndex(['2010-04-01', '2012-02-03'], dtype='datetime64[ns]', freq=None)
按照年份、(n)月份、天取数据
按年度取数据
data['2012']
data['2009':'2012']
data['2012-01']
data.index.year提取时间index年份信息
data.index.year 从index中将年份从index中提取出来
- 每年的最大值:
data['year']=data.index.year
data.groupby('year').max()
- 每月的最大值,按照月份(所有年份的月份)
data['month']=data.index.month
data.groupby('month').max()
- 每周的最大值(0是周一,0~6表示周一到周六):
data['weekday'] = data.index.weekday``
data.groupby(‘weekday’).max()` - 周末(5、6)
data.weekday.isin([5,6])
返回的是false、true,是否是周末的布尔,等同于:data[weekday].isin([5,6])
data.groupby(data.weekday.isin([5,6])).max()
返回的分组index为False,True
resample()抽样函数
- resample(‘A’) #按年份抽样,默认 how = ‘mean’
resample(‘A’,how=‘mean’)
data[‘year’].resample(‘A’,how=‘mean’) #resample(‘A’,how=‘mean’)抽样结果放入data[‘year’]中 - 按照月份抽样
data[‘month’].resample(‘M’,how=‘mean’) - 按照10个月
data['10_month'].resample('10M',how='mean')
- 按照天
data['day'].resample('D',how='mean')
- 金融领域应用:
import pandas as pd
import numpy as np
data=pd.DataFrame({'price':{949.94,941.37,949.97}},{'volumn':{0.01,0.01,0.01}})
data['timer'] = ['2014-01-15 14:29:54','2014-01-15 14:29:59','2014-01-15 14:30:17']
data.dtypes
data.timer = pd.Datetime(data.timer)
data.set_index('timer',inplace='True')
a1=data.resample('30s',how={'price':'ohic'})
a2 = data.resample('30s',how={'volumn':'sum'})
a1['volumn'] = a2
a1
data.resample('30s',how={'price':'ohic','volumn':'sum'})
- 抽样函数与分组group by实现抽样的区别:
resample抽样直接抽取,不要设置标签,比如按十个月抽取,直接’10M’;但是groupby需要设置10yue的标签,然后按照标签抽取
年份index例子:
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn
pd.options.display.max_rows = 8
#AirBase (The European Air quality dataBase): hourly measurements of all air quality monitoring stations from Europe
#Starting from these hourly data for different stations:
import airbase
data = airbase.load_data()
data['1999':].resample('A').plot(ylim=[0,100])
#How many exceedances of the limit values?
exceedances = data > 200
exceedances = exceedances.groupby(exceedances.index.year).sum()
ax = exceedances.loc[2005:].plot(kind='bar')
ax.axhline(18, color='k', linestyle='--')
#What is the difference in diurnal profile between weekdays and weekend?
data['weekday'] = data.index.weekday
data['weekend'] = data['weekday'].isin([5, 6])
data_weekend = data.groupby(['weekend', data.index.hour])['FR04012'].mean().unstack(level=0)
data_weekend.plot()
17、python mysql(sqlalchemy+pandas)
python mysql
两种方法,推荐第一种方法
M1、sqlalchemy包建立数据库链接,pandas读取sql
from sqlalchemy import create_engine
import pandas as pd
#建立数据库链接
#用户名
mysql_engine = create_engine("mysql+pymysql://root:35230479187.190.26.22:3306/winds")
#root用户名;35230479密码,187.190.26.22ip地址,端口号:3306,数据库名称winds
#pandas read_sql,返回dataframe mydata
mydata = pd.read_sql('select id,name,birthday from test.t1',mysql_engine)
#to_sql 将数据读写到数据库中,在数据库中必须存在表名和字段名,才可以读取成功
M2、不推荐
import pyodbc # If using PostgreSQL, MySQL, SQLite, Redshift, MS SQL Server, or Oracle, use db.py instead
import pandas as pd
from getpass import getpass # Module that will create a text input widget AND mask your password
userid = 'your_userid'
pw = getpass(prompt='Enter your password: ')
cnxn_string = 'DSN=your_dsn;UID=' + userid + ';PWD=' + pw
cnxn = pyodbc.connect(cnxn_string)
cursor = cnxn.cursor()
sql = """
SELECT * from your_table...
"""
df = pd.read_sql(sql, cnxn, index_col=None, parse_dates={'some_column':"%Y-%m-%d"})
# Close connections
cursor.close()
cnxn.close()
18、 强制类型转换
pandas.to_datetime : Convert argument to datetime.
pandas.to_timedelta : Convert argument to timedelta.
pandas.to_numeric : Convert argument to a numeric type.
numpy.ndarray.astype : Cast a numpy array to a specified type.
Signature: df1.astype(dtype, copy=True, errors='raise', **kwargs)
Docstring:
Cast a pandas object to a specified dtype ``dtype``.
Parameters
----------
dtype : data type, or dict of column name -> data type
Use a numpy.dtype or Python type to cast entire pandas object to
the same type. Alternatively, use {col: dtype, ...}, where col is a
column label and dtype is a numpy.dtype or Python type to cast one
or more of the DataFrame's columns to column-specific types.
copy : bool, default True.
Return a copy when ``copy=True`` (be very careful setting
``copy=False`` as changes to values then may propagate to other
pandas objects).
errors : {'raise', 'ignore'}, default 'raise'.
Control raising of exceptions on invalid data for provided dtype.
- ``raise`` : allow exceptions to be raised
- ``ignore`` : suppress exceptions. On error return original object
.. versionadded:: 0.20.0
raise_on_error : raise on invalid input
.. deprecated:: 0.20.0
Use ``errors`` instead
kwargs : keyword arguments to pass on to the constructor
Returns
-------
casted : type of caller
Examples
--------
>>> ser = pd.Series([1, 2], dtype='int32')
>>> ser
0 1
1 2
dtype: int32
>>> ser.astype('int64')
0 1
1 2
dtype: int64
Convert to categorical type:
>>> ser.astype('category')
0 1
1 2
dtype: category
Categories (2, int64): [1, 2]
Convert to ordered categorical type with custom ordering:
>>> ser.astype('category', ordered=True, categories=[2, 1])
0 1
1 2
dtype: category
Categories (2, int64): [2 < 1]
Note that using ``copy=False`` and changing data on a new
pandas object may propagate changes:
>>> s1 = pd.Series([1,2])
>>> s2 = s1.astype('int64', copy=False)
>>> s2[0] = 10
>>> s1 # note that s1[0] has changed too
0 10
1 2
dtype: int64
19、DataFrame运算——累计统计函数
- cumsum()函数:求前n个元素的累加值
- cummax()函数:求前n个元素中的最大值
- cummin()函数:求前n个元素中的最大值
- cumprod()函数:求前n个元素的累乘积
series_data.cumprod(axis = 0) # 按列累乘,输出series,行数同series_data
series_data.cumprod(axis = 0).iloc[-1] # 取最后一个全部数据的累乘
20、pandas 索引用法
1.set_index
DataFrame可以通过set_index方法,可以设置单索引和复合索引。
DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)
append添加新索引,drop为False,inplace为True时,索引将会还原为列
2.reset_index
reset_index可以还原索引,重新变为默认的整型索引
DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill=”)
level控制了具体要还原的那个等级的索引
drop为False则索引列会被还原为普通列,否则会丢失
21、lambda函数和if判断使用
- lambda x: 语句1 if 条件1 else 语句2 if 条件2 else 语句3
实际上是下面这样表达 - lambda x: 语句1 if 条件1 else ( 语句2 if 条件2 else 语句3 )
22、DataFrame.apply与GroupBy.apply比较
DataFrame.apply操作的对象是DataFrame的一行或者一列,
通过axis来指定行或者列,最终返回的类型取决于apply函数操作的结果。
GroupBy.apply是将一个(已经分过组的)dataframe作为输入,
对每个group进行操作后,将结果整合为一个dataframe或者series或者标量返回。
https://blog.csdn.net/S_o_l_o_n/article/details/80897376
我们经常会对DataFrame对象中的某些行或列,或者对DataFrame对象中的所有元素进行某种运算或操作,我们无需利用低效笨拙的循环,DataFrame给我们分别提供了相应的直接而简单的方法,apply()和applymap()。其中apply()方法是针对某些行或列进行操作的,而applymap()方法则是针对所有元素进行操作的。
我们给出具体的例子看这两个方法是怎么工作的,代码入下。首先我们构造一个(3,4)的DataFrame对象df1,然后我们想对每列进行求和,便可以利用apply()方法结合匿名函数lambda实现。apply()方法中的第一个参数是函数,这里我们传递了一个匿名函数给apply(),当然我们还可以通过axis参数指定轴,比如这里我们可以令axis=1,则就会返回每行的求和,这里默认axis=0。
然后如果我们想对df1中的每个元素进行操作,比如这个例子中我们是想让每个元素只保留两位小数,那么可以通过applymap()方法实现。applymap()方法就是针对元素级的方法,比如在in[20]中,我们通过给applymap()方法传递一个格式化表达的匿名函数,通过applymap()方法将这个函数应用到每个元素上以实现我们的目标。这里之所以叫applymap()方法,是因为在Series中有一个对元素级操作的map()方法,参数也为函数。
当然,一些常用的运算和统计方法,DataFrame都是自己定义了的,因此我们不用自己再构造匿名函数。但是一般的,DataFrame自己的运算方法都是针对所有的行或所有列的,具体是行还是列可以通过axis参数指定。
23、data.drop_duplicates删除重复数据,
keep参数可以选择保留哪一条数据
data.drop_duplicates(subset='列名',keep='first',inplace=True)
subset:column label or sequence of labels, optional ,用来指定特定的列,默认所有列
keep:{‘first’, ‘last’, False}, default ‘first’ ,删除重复项并保留第一次出现的项
inplace:boolean, default False ,是否直接修改原 dataframe
24、drop函数删除某列某行 pd.DataFrame.drop()
df.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors='raise')
labels:指示标签,表示行标或列标;
axis = 0:默认取 0,表示删除集合的行;
axis = 1:删除集合中的列;
index:删除行;
columns:删除列;
level:针对有两级行标或列标的集合;如下图,集合有两级行标;
level = 1:表示按第2级行删除整行;(即speed、weight、length)
level = 0:默认取 0,表示按第1级行标删除整行;(即speed、cow、falcon,此处一次删除 3 行数据)
DF= DF.drop('column_name', axis=1);
DF.drop('column_name',axis=1, inplace=True)
DF.drop([DF.columns[[0,1, 3]]], axis=1, inplace=True) # Note: zero indexed
drop函数默认删除行,列需要加axis = 1
注意:凡是会对原数组作出修改并返回一个新数组的, 往往都有一个 inplace可选参数。如果手动设定为True(默认为False),
那么原数组直接就被替换。
25、数据关联merge
merge(left, right, how='inner', on=None, left_on=None, right_on=None, \ left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), \ copy=True, indicator=False, validate=None)
26、数据类型转换 DataFrame.astype() 方法
df[‘Name’] = df[‘Name’].astype(np.datetime64)
DataFrame.astype() 方法可对整个DataFrame或某一列进行数据格式转换,支持Python和NumPy的数据类型。
27、清理无效数据 df.dropna() df[df.notnull()]
df[df.isnull()] #返回的是个true或false的Series对象(掩码对象),进而筛选出我们需要的特定数据。
df[df.notnull()]
df.dropna() #将所有含有nan项的row删除
df.dropna(axis=1,thresh=3) #将在列的方向上三个为NaN的项删除
df.dropna(how=‘ALL’) #将全部项都是nan的row删除
此处:print data.dropna() 和 print data[data.notnull()] 结果一样
填充无效值
df.fillna(0)
df.fillna({1:0, 2:0.5}) #对第一列nan值赋0,第二列赋值0.5
df.fillna(method=‘ffill’) #在列方向上以前一个值作为值赋给NaN
28、给DataFrame的列命名或重命名
M1.读取文件的时候重命名 names = new_col,可以在读取文件的时候,给出新列名。
new_col = [‘new1’, ‘new2’,… , ‘newn’]
pd.read_csv(‘data’, names = new_col, header=0)
M2.全部重命名 columns = new_columns,新列名的长度必须与旧列名一致
new_col = [‘new1’, ‘new2’,… , ‘newn’]
dataframe.columns = new_col
M3.部分重命名columns = dict,使用字典类型的数据对列进行重命名。
dataframe.rename(columns = {“old_name”: “new_name”})
dataframe.rename(columns = {“old1”: “new1”, “old2”:“new2”}, inplace=True)
M4.使用str.replace
dataframe.columns = dataframe.columns.str.replace('' '', ''_'')
29、DataFrame对象groupby.agg方法
GroupBy为对原DataFrame进行打包分组,agg为聚合(其操作包括max、min、std、sum、count)
df = pd.DataFrame({‘A’: [1, 1, 2, 2],‘B’: [1, 2, 3, 4],‘C’: np.random.randn(4)})
M1、The aggregation is for each column:
(根据Dataframe的列’A’进行划分,再进行1项聚合操作,原DataFrame的其他各列各产生1列)
df.groupby('A').agg('min')
M2、Multiple aggregations:
(聚合后的多项操作,其他列的每列会各自产生多列)
df.groupby(‘A’).agg([‘min’, ‘max’])
M3、Select a column for multiple aggregation
(聚合后选择1列‘B’进行多项操作,产生多列)
df.groupby('A').B.agg(['min', 'max'])
M4、Select several columns for multiple aggregation
(聚合后选择1列进行多项操作,产生多列,并存为新列名)
df.groupby('A').B.agg({'B_max': 'max', 'B_min': 'min'})
B_max B_min
A
1 2 1
2 4 3
M5、Select several columns for multiple aggregation
( 聚合后选择多列进行多种操作)
df.groupby('A').agg({'B': ['min', 'max'], 'C': min})
B C
min max min
A
1 1 2 0.227877
2 3 4 -0.562860