pandas 细节总结

pandas 细节总结

数据处理总结

采样

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 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值