在使用python进行数据分析的过程中,采用groupby函数对数据进行分组是一项很常用的操作。
python中groupby函数主要的作用是进行数据的分组以及分组后地组内运算!
对于数据的分组和分组运算主要是指groupby函数的应用,具体函数的规则如下:df[](指输出数据的结果属性名称).groupby([df[属性],df[属性])(指分类的属性,数据的限定定语,可以有多个).mean()
(对于数据的计算方式——函数名称)
示例:
data.groupby(group)[feature].agg([sum, min, max, np.mean]).reset_index()
#根据gruop分组,并计算特征feature的和、最小、最大和平均值数据
根据类别分组,然后计算每个类别下的feature特征的和、最小、最大和平均值。(就是说:按照类别分组,每个数据在组内的情况)
group_list = ['HYZK', 'ZHIYE', 'ZHICHEN', ...]
num_feature_list = ['GRYJCE', 'DKFFE', 'DKLL', ...]
for group in group_list:
for feature in num_feature_list:
#根据类别分组,然后计算每个类别下的feature特征的和、最小、最大和平均值。
tmp = data.groupby(group)[feature].agg([sum, min, max, np.mean]).reset_index()
tmp = pd.merge(data, tmp, on=group, how='left')
data['{}-mean_gb_{}'.format(feature, group)] = data[feature] - tmp['mean']
data['{}-min_gb_{}'.format(feature, group)] = data[feature] - tmp['min']
data['{}-max_gb_{}'.format(feature, group)] = data[feature] - tmp['max']
data['{}/sum_gb_{}'.format(feature, group)] = data[feature] / tmp['sum']
这是由于变量grouped是一个GroupBy对象,它实际上还没有进行任何计算,只是含有一些有关分组键df[‘key1’]的中间数据而已,然后我们可以调用配合函数(如:.mean()方法)来计算分组平均值等。
因此,一般为方便起见可直接在聚合之后+“配合函数”,默认情况下,所有数值列都将会被聚合,虽然有时可能会被过滤为一个子集。
一般,如果对df直接聚合时,
df.groupby([df[‘key1’],df[‘key2’]]).mean()(分组键为:Series)与df.groupby([‘key1’,‘key2’]).mean()(分组键为:列名)是等价的,输出结果相同。
但是,如果对df的指定列进行聚合时,
df[‘data1’].groupby(df[‘key1’]).mean()(分组键为:Series),唯一方式。
此时,直接使用“列名”作分组键,提示“Error Key”。
注意:分组键中的任何缺失值都会被排除在结果之外。
(1)根据key1键对data1列数据聚合
df.groupby('key1')['data1'].mean()
#或者
df['data1'].groupby(df['key1']).mean()
(2)当对多列数据如data1和data2根据某个键入key1聚合分组时,组引入列表['data1','data2'],此处对data2外加中括号是一个意思,只是影响输出格式。
根据key1键对data1和data2列数据聚合
df.groupby('key1')[['data1','data2']].mean()
#或者
df[['data1','data2']].groupby(df['key1']).mean()
(3)根据多个键key1、key2对data2列数据聚合
df.groupby(['key1','key2'])['data2'].mean()
#或者
df['data2'].groupby([df['key1'],df['key2']]).mean()
会根据提供的函数对指定序列做映射。
示例:
data['XUELI'].value_counts()
结果:99出现了54994次,0出现了6次
99 54994
0 6
Name: XUELI, dtype: int64
data['XUELI'].map(data['XUELI'].value_counts())
结果:99的全部映射为次数54994,0的全部映射为次数6
0 54994
1 54994
2 54994
3 54994
4 54994
...
54995 54994
54996 54994
54997 54994
54998 54994
54999 54994
Name: XUELI, Length: 55000, dtype: int64
参数格式
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=('_x', '_y'), copy=True, indicator=False,
validate=None)
参数如下:
left
:拼接的左侧DataFrame对象
right:
拼接的右侧DataFrame对象
on:
要加入的列或索引级别名称。 必须在左侧和右侧DataFrame对象中找到。如果未传递且left_index和right_index为False,则DataFrame中的列的交集将被推断为连接键。
left_on:左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
right_on: 左侧DataFrame中的列或索引级别用作键。 可以是列名,索引级名称,也可以是长度等于DataFrame长度的数组。
eft_index: 如果为True,则使用左侧DataFrame中的索引(行标签)作为其连接键。
对于具有MultiIndex(分层)的DataFrame,级别数必须与右侧DataFrame中的连接键数相匹配。
right_index: 与left_index功能相似。
how
: One of ‘left’, ‘right’, ‘outer’, ‘inner’.默认inner。inner是取交集,outer取并集。比如left[‘A’,‘B’,‘C’];right[’'A,‘C’,‘D’];inner取交集的话,left中出现的A会和right中出现的买一个A进行匹配拼接,如果没有是B,在right中没有匹配到,则会丢失。'outer’取并集,出现的A会进行一一匹配,没有同时出现的会将缺失的部分添加缺失值。
sort: 按字典顺序通过连接键对结果DataFrame进行排序。 默认为True,设置为False将在很多情况下显着提高性能。
suffixes: 用于重叠列的字符串后缀元组。 默认为(‘x’,’ y’)。
copy: 始终从传递的DataFrame对象复制数据(默认为True),即使不需要重建索引也是如此。
indicator:将一列添加到名为_merge的输出DataFrame,其中包含有关每行源的信息。_merge是分类类型,并且对于其合并键仅出现在“左”DataFrame中的观察值,取得值为left_only,对于其合并键仅出现在“右”DataFrame中的观察值为right_only,并且如果在两者中都找到观察点的合并键,则为left_only。
示例代码:
import pandas as pd
left = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({
'key': ['K0', 'K1', 'K2', 'K3'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right, on='key')
# on参数传递的key作为连接键
result
Out[4]:
A B key C D
0 A0 B0 K0 C0 D0
1 A1 B1 K1 C1 D1
2 A2 B2 K2 C2 D2
3 A3 B3 K3 C3 D3
Merge method
如果组合键没有出现在左表或右表中,则连接表中的值将为NA。
a1 = pd.DataFrame({
'a': [1, 1, 2, 2, 2, 6, 7, 8, 10],
'b': [1, 2, 3, 4, 5, 6, 7, 8, 9],
'c': [1, 2, 3, 4, 5, 6, 7, 8, 9]
})
a2 = pd.DataFrame({
'a': [1, 1, 2, 4, 5, 6, 7, 8, 11],
'b': ['w', 'e', '2对应的出现3次', 4, 5, 6, 7, 8, 9],
'c': ['d', 'g', '2对应的出现3次', 4, 5, 6, 7, 8, 9]
})
a3 = pd.merge( left = a1, right = a2, on = ['a'], how = 'left')
print(a3)
# a b_x c_x b_y c_y
# 0 1 1 1 w d
# 1 1 1 1 e g
# 2 1 2 2 w d
# 3 1 2 2 e g
# 4 2 3 3 2对应的出现3次 2对应的出现3次
# 5 2 4 4 2对应的出现3次 2对应的出现3次
# 6 2 5 5 2对应的出现3次 2对应的出现3次
# 7 6 6 6 6 6
# 8 7 7 7 7 7
# 9 8 8 8 8 8
# 10 10 9 9 NaN NaN
比赛中用到示例:
train_data = pd.merge(base_info, entprise_info, on='id')
train_data = pd.merge(train_data, other_info, on='id', how='left')
train_data = pd.merge(train_data, news_info_df, on='id', how='left')
train_data = pd.merge(train_data, tax_info_df, on='id', how='left')
train_data = pd.merge(train_data, annual_report_info_df, on='id', how='left')
train_data = pd.merge(train_data, change_info_df, on='id', how='left')
意思就是重新排序
通过reset_index()方法我们可以重置索引,drop参数为True时,直接丢弃原来的
索引,否则原来的索引新生成一列名为'index'的列:
df.reset_index(inplace=True,drop=True)
astype()函数可用于转化dateframe某一列的数据类型
如下将dateframe某列的str类型转为int,注意astype()没有replace=True的用法,想要在原数据上修改,要写成如下形式。
注意只有当该列的字符串全是由纯数字构成时才可以这样写,如果混有字母,会报错:ValueError: invalid literal for int() with base 10:
示例:
```python
cat_col = ['HYZK', 'ZHIYE', 'ZHICHEN','DWJJLX', 'DWSSHY', 'GRZHZT']
X_train[cat_col] = X_train[cat_col].astype('category')
X_test[cat_col] = X_test[cat_col].astype('category')
用duplicated( )函数判断
C.duplicated()
DataFrame 删除重复数据 duplicated函数
Pandas nunique() 用于获取唯一值的统计次数。
#训练集中的用户数量为20w
trn_click.user_id.nunique()
apply函数是pandas
里面所有函数中自由度最高的函数。该函数如下:
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
该函数最有用的是第一个参数,这个参数是函数,相当于C/C++的函数指针。
这个函数需要自己实现,函数的传入参数根据axis来定,比如axis = 1,就会把一行数据作为Series的数据结构传入给自己实现的函数中,我们在函数中实现对Series不同属性之间的计算,返回一个结果,则apply函数会自动遍历每一行DataFrame的数据,最后将所有结果组合成一个Series数据结构并返回。
news_info['public_date'] = news_info['public_date'].apply(lambda x: x if '-' in str(x) else np.nan)#处理时间
python中lambda函数
lambda是Python预留的关键字
lambda函数的特性:
示例:
news_info['public_date'] = news_info['public_date'].apply(lambda x: x if '-' in str(x) else np.nan)#处理时间
参考:
[1]https://zhuanlan.zhihu.com/p/109591980(groupby)
[2]https://www.cnblogs.com/Yanjy-OnlyOne/p/11217802.html(groupby)
[3]https://zhuanlan.zhihu.com/p/86350553(transfrom)
[4]https://blog.csdn.net/brucewong0516/article/details/82707492(merge)
[5]https://www.cnblogs.com/wind666/p/10703064.html(lambda)
记录时间:2020年12月13日