pyhton-聚合分组操作grouby

Data Aggregation
# 10.2 数据聚合
# 聚合指的是任何能够从数组产⽣标量值的数据转换过程。之前的
# 例⼦已经⽤过⼀些,⽐如mean、count、min以及sum等。你可
# 能想知道在GroupBy对象上调⽤mean()时究竟发⽣了什么。许多
# 常⻅的聚合运算(如表10-1所示)都有进⾏优化。然⽽,除了这
# 些⽅法,你还可以使⽤其它的。
# 例如,quantile可以计算Series或DataFrame389
# 列的样本分位数。
df
grouped = df.groupby('key1')
grouped['data1'].quantile(0.9)
key1
a 1.668413
b -0.523068
Name: data1, dtype: float64
如果要使⽤你⾃⼰的聚合函数,只需将其传⼊aggregate或agg⽅
# 法即可: 使用自己的聚合函数
# 如果要使⽤你⾃⼰的聚合函数,只需将其传⼊aggregate或agg⽅
# 法即可: 使用自己的聚合函数
def peak_to_peak(arr):
return arr.max() - arr.min()
grouped.agg(peak_to_peak)
grouped.describe()
Column-Wise and Multiple Function Application
⾯向列的多函数应⽤
# 回到前⾯⼩费的例⼦。使⽤read_csv导⼊数据之后,我们添加了
# ⼀个⼩费百分⽐的列tip_pct:
# ⾯向列的多函数应⽤
# 回到前⾯⼩费的例⼦。使⽤read_csv导⼊数据之后,我们添加了
# ⼀个⼩费百分⽐的列tip_pct:
tips = pd.read_csv('examples/tips.csv')
# Add tip percentage of total bill
tips['tip_pct'] = tips['tip'] / tips['total_bill']
tips[:6]
total_bill tip smoker day time size tip_pct
0 16.99 1.01 No Sun Dinner 2 0.059447
1 10.34 1.66 No Sun Dinner 3 0.160542
2 21.01 3.50 No Sun Dinner 3 0.166587
3 23.68 3.31 No Sun Dinner 2 0.139780
4 24.59 3.61 No Sun Dinner 4 0.146808
5 25.29 4.71 No Sun Dinner 4 0.186240
# 你已经看到,对Series或DataFrame列的聚合运算其实就是使⽤
# aggregate(使⽤⾃定义函数)或调⽤诸如mean、std之类的⽅
# 法。然⽽,你可能希望对不同的列使⽤不同的聚合函数,或⼀次
# 应⽤多个函数。其实这也好办,我将通过⼀些示例来进⾏讲解。
# ⾸先,我根据天和smoker对tips进⾏分组:
grouped = tips.groupby(['day', 'smoker'])
grouped_pct = grouped['tip_pct']
grouped_pct.agg('mean')
day smoker
Fri No 0.151650
Yes 0.174783
Sat No 0.158048
Yes 0.147906
Sun No 0.160113
Yes 0.187250
Thur No 0.160298
Yes 0.163863
Name: tip_pct, dtype: float64
# 如果传⼊⼀组函数或函数名,得到的DataFrame的列就会以相应
# 的函数命名:
grouped_pct.agg(['mean', 'std', peak_to_peak])
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-41-9758eaedd62a> in <module>()
1 # 如果传⼊⼀组函数或函数名,得到的DataFrame的列就会以相应
2 # 的函数命名:
----> 3 grouped_pct.agg(['mean', 'std', peak_to_peak])

NameError: name 'peak_to_peak' is not defined
你并⾮⼀定要接受GroupBy⾃动给出的那些列名,特别是lambda
# 函数,它们的名称是'',这样的辨识度就很低了(通过
# 函数的name属性看看就知道了)。因此,如果传⼊的是⼀个由
# (name,function)元组组成的列表,则各元组的第⼀个元素就会被
# ⽤作DataFrame的列名(可以将这种⼆元元组列表看做⼀个有序
# 映射):
# 你并⾮⼀定要接受GroupBy⾃动给出的那些列名,特别是lambda
# 函数,它们的名称是'',这样的辨识度就很低了(通过
# 函数的name属性看看就知道了)。因此,如果传⼊的是⼀个由
# (name,function)元组组成的列表,则各元组的第⼀个元素就会被
# ⽤作DataFrame的列名(可以将这种⼆元元组列表看做⼀个有序
# 映射):
grouped_pct.agg([('foo', 'mean'), ('bar', np.std)])
foo bar
day smoker
Fri No 0.151650 0.028123
Yes 0.174783 0.051293
Sat No 0.158048 0.039767
Yes 0.147906 0.061375
Sun No 0.160113 0.042347
Yes 0.187250 0.154134
Thur No 0.160298 0.038774
Yes 0.163863 0.039389
对于DataFrame,你还有更多选择,你可以定义⼀组应⽤于全部
# 列的⼀组函数,或不同的列应⽤不同的函数。假设我们想要对
# tip_pct和total_bill列计算三个统计信息:
# 对于DataFrame,你还有更多选择,你可以定义⼀组应⽤于全部
# 列的⼀组函数,或不同的列应⽤不同的函数。假设我们想要对
# tip_pct和total_bill列计算三个统计信息:
functions = ['count', 'mean', 'max']
result = grouped['tip_pct', 'total_bill'].agg(functions)
result
tip_pct total_bill
count mean max count mean max
day smoker
Fri No 4 0.151650 0.187735 4 18.420000 22.75
Yes 15 0.174783 0.263480 15 16.813333 40.17
Sat No 45 0.158048 0.291990 45 19.661778 48.33
Yes 42 0.147906 0.325733 42 21.276667 50.81
Sun No 57 0.160113 0.252672 57 20.506667 48.17
Yes 19 0.187250 0.710345 19 24.120000 45.35
Thur No 45 0.160298 0.266312 45 17.113111 41.19
Yes 17 0.163863 0.241255 17 19.190588 43.11
result['tip_pct']
ftuples = [('Durchschnitt', 'mean'), ('Abweichung', np.var)]
grouped['tip_pct', 'total_bill'].agg(ftuples)
现在,假设你想要对⼀个列或不同的列应⽤不同的函数。具体的
# 办法是向agg传⼊⼀个从列名映射到函数的字典:
# 现在,假设你想要对⼀个列或不同的列应⽤不同的函数。具体的
# 办法是向agg传⼊⼀个从列名映射到函数的字典:
grouped.agg({'tip' : np.max, 'size' : 'sum'})
grouped.agg({'tip_pct' : ['min', 'max', 'mean', 'std'],
'size' : 'sum'})
tip_pct size
min max mean std sum
day smoker
Fri No 0.120385 0.187735 0.151650 0.028123 9
Yes 0.103555 0.263480 0.174783 0.051293 31
Sat No 0.056797 0.291990 0.158048 0.039767 115
Yes 0.035638 0.325733 0.147906 0.061375 104
Sun No 0.059447 0.252672 0.160113 0.042347 167
Yes 0.065660 0.710345 0.187250 0.154134 49
Thur No 0.072961 0.266312 0.160298 0.038774 112
Yes 0.090014 0.241255 0.163863 0.039389 40
Returning Aggregated Data Without Row Indexes
以“没有⾏索引”的形式返回聚合数据
# 到⽬前为⽌,所有示例中的聚合数据都有由唯⼀的分组键组成的
# 索引(可能还是层次化的)。由于并不总是需要如此,所以你可
# 以向groupby传⼊as_index=False以禁⽤该功能:
# 以“没有⾏索引”的形式返回聚合数据
# 到⽬前为⽌,所有示例中的聚合数据都有由唯⼀的分组键组成的
# 索引(可能还是层次化的)。由于并不总是需要如此,所以你可
# 以向groupby传⼊as_index=False以禁⽤该功能:
tips.groupby(['day', 'smoker'], as_index=False).mean()
day smoker total_bill tip size tip_pct
0 Fri No 18.420000 2.812500 2.250000 0.151650
1 Fri Yes 16.813333 2.714000 2.066667 0.174783
2 Sat No 19.661778 3.102889 2.555556 0.158048
3 Sat Yes 21.276667 2.875476 2.476190 0.147906
4 Sun No 20.506667 3.167895 2.929825 0.160113
5 Sun Yes 24.120000 3.516842 2.578947 0.187250
6 Thur No 17.113111 2.673778 2.488889 0.160298
7 Thur Yes 19.190588 3.030000 2.352941 0.163863
Apply: General split-apply-combine
10.3 apply:⼀般性的“拆分-应⽤-合并”
# 最通⽤的GroupBy⽅法是apply,本节剩余部分将重点讲解它。
# 如图10-2所示,apply会将待处理的对象拆分成多个⽚段,然后
# 对各⽚段调⽤传⼊的函数,最后尝试将各⽚段组合到⼀起。
# 10.3 apply:⼀般性的“拆分-应⽤-合并”
# 最通⽤的GroupBy⽅法是apply,本节剩余部分将重点讲解它。
# 如图10-2所示,apply会将待处理的对象拆分成多个⽚段,然后
# 对各⽚段调⽤传⼊的函数,最后尝试将各⽚段组合到⼀起。
def top(df, n=5, column='tip_pct'):
return df.sort_values(by=column)[-n:]
top(tips, n=6)
total_bill tip smoker day time size tip_pct
109 14.31 4.00 Yes Sat Dinner 2 0.279525
183 23.17 6.50 Yes Sun Dinner 4 0.280535
232 11.61 3.39 No Sat Dinner 2 0.291990
67 3.07 1.00 Yes Sat Dinner 1 0.325733
178 9.60 4.00 Yes Sun Dinner 2 0.416667
172 7.25 5.15 Yes Sun Dinner 2 0.710345
现在,如果对smoker分组并⽤该函数调⽤apply,就会得到:
# 现在,如果对smoker分组并⽤该函数调⽤apply,就会得到:
tips.groupby('smoker').apply(top)
total_bill tip smoker day time size tip_pct
smoker
No 88 24.71 5.85 No Thur Lunch 2 0.236746
185 20.69 5.00 No Sun Dinner 5 0.241663
51 10.29 2.60 No Sun Dinner 2 0.252672
149 7.51 2.00 No Thur Lunch 2 0.266312
232 11.61 3.39 No Sat Dinner 2 0.291990
Yes 109 14.31 4.00 Yes Sat Dinner 2 0.279525
183 23.17 6.50 Yes Sun Dinner 4 0.280535
67 3.07 1.00 Yes Sat Dinner 1 0.325733
178 9.60 4.00 Yes Sun Dinner 2 0.416667
172 7.25 5.15 Yes Sun Dinner 2 0.710345
最终结果就有了⼀个层次化索引,其内层索引值来⾃
# 原DataFrame。
# 如果传给apply的函数能够接受其他参数或关键字,则可以将这
# 些内容放在函数名后⾯⼀并传⼊:
# 最终结果就有了⼀个层次化索引,其内层索引值来⾃
# 原DataFrame。
# 如果传给apply的函数能够接受其他参数或关键字,则可以将这
# 些内容放在函数名后⾯⼀并传⼊:
tips.groupby(['smoker', 'day']).apply(top, n=1, column='total_bill')
total_bill tip smoker day time size tip_pct
smoker day
No Fri 94 22.75 3.25 No Fri Dinner 2 0.142857
Sat 212 48.33 9.00 No Sat Dinner 4 0.186220
Sun 156 48.17 5.00 No Sun Dinner 6 0.103799
Thur 142 41.19 5.00 No Thur Lunch 5 0.121389
Yes Fri 95 40.17 4.73 Yes Fri Dinner 4 0.117750
Sat 170 50.81 10.00 Yes Sat Dinner 3 0.196812
Sun 182 45.35 3.50 Yes Sun Dinner 3 0.077178
Thur 197 43.11 5.00 Yes Thur Lunch 4 0.115982
可能你已经想起来了,之前我在GroupBy对象上调⽤过
# describe:
# 可能你已经想起来了,之前我在GroupBy对象上调⽤过
# describe:
result = tips.groupby('smoker')['tip_pct'].describe()
result
result.unstack('smoker')
smoker
count No 151.000000
Yes 93.000000
mean No 0.159328
Yes 0.163196
std No 0.039910
Yes 0.085119
min No 0.056797
Yes 0.035638
25% No 0.136906
Yes 0.106771
50% No 0.155625
Yes 0.153846
75% No 0.185014
Yes 0.195059
max No 0.291990
Yes 0.710345
dtype: float64
f = lambda x: x.describe() grouped.apply(f)

Suppressing the Group Keys
禁⽌分组键
# 从上⾯的例⼦中可以看出,分组键会跟原始对象的索引共同构成
# 400
# 结果对象中的层次化索引。将group_keys=False传⼊groupby即
# 可禁⽌该效果:
# 禁⽌分组键
# 从上⾯的例⼦中可以看出,分组键会跟原始对象的索引共同构成
# 400
# 结果对象中的层次化索引。将group_keys=False传⼊groupby即
# 可禁⽌该效果:
tips.groupby('smoker', group_keys=False).apply(top)
total_bill tip smoker day time size tip_pct
88 24.71 5.85 No Thur Lunch 2 0.236746
185 20.69 5.00 No Sun Dinner 5 0.241663
51 10.29 2.60 No Sun Dinner 2 0.252672
149 7.51 2.00 No Thur Lunch 2 0.266312
232 11.61 3.39 No Sat Dinner 2 0.291990
109 14.31 4.00 Yes Sat Dinner 2 0.279525
183 23.17 6.50 Yes Sun Dinner 4 0.280535
67 3.07 1.00 Yes Sat Dinner 1 0.325733
178 9.60 4.00 Yes Sun Dinner 2 0.416667
172 7.25 5.15 Yes Sun Dinner 2 0.710345
Quantile and Bucket Analysis
分位数和桶分析
# 我曾在第8章中讲过,pandas有⼀些能根据指定⾯元或样本分位
# 数将数据拆分成多块的⼯具(⽐如cut和qcut)。将这些函数跟
# groupby结合起来,就能⾮常轻松地实现对数据集的桶
# (bucket)或分位数(quantile)分析了。以下⾯这个简单的随
# 机数据集为例,我们利⽤cut将其装⼊⻓度相等的桶中:
# 分位数和桶分析
# 我曾在第8章中讲过,pandas有⼀些能根据指定⾯元或样本分位
# 数将数据拆分成多块的⼯具(⽐如cut和qcut)。将这些函数跟
# groupby结合起来,就能⾮常轻松地实现对数据集的桶
# (bucket)或分位数(quantile)分析了。以下⾯这个简单的随
# 机数据集为例,我们利⽤cut将其装⼊⻓度相等的桶中:
frame = pd.DataFrame({'data1': np.random.randn(1000),
'data2': np.random.randn(1000)})
quartiles = pd.cut(frame.data1, 4)
quartiles[:10]
0 (-1.23, 0.489]
1 (-1.23, 0.489]
2 (-1.23, 0.489]
3 (-1.23, 0.489]
4 (-1.23, 0.489]
5 (-1.23, 0.489]
6 (-2.956, -1.23]
7 (0.489, 2.208]
8 (0.489, 2.208]
9 (-1.23, 0.489]
Name: data1, dtype: category
Categories (4, interval[float64]): [(-2.956, -1.23] < (-1.23, 0.489] < (0.489, 2.208] < (2.208, 3.928]]
由cut返回的Categorical对象可直接传递到groupby。因此,我们
# 可以像下⾯这样对data2列做⼀些统计计算:
# 由cut返回的Categorical对象可直接传递到groupby。因此,我们
# 可以像下⾯这样对data2列做⼀些统计计算:
def get_stats(group):
return {'min': group.min(), 'max': group.max(),
'count': group.count(), 'mean': group.mean()}
grouped = frame.data2.groupby(quartiles)
grouped.apply(get_stats).unstack()
count max mean min
data1
(-2.956, -1.23] 92.0 1.670835 -0.038501 -3.399312
(-1.23, 0.489] 602.0 3.260383 -0.019113 -2.989741
(0.489, 2.208] 294.0 2.954439 0.066179 -3.745356
(2.208, 3.928] 12.0 1.765640 -0.048003 -1.929776
这些都是⻓度相等的桶。要根据样本分位数得到⼤⼩相等的桶,
# 使⽤qcut即可。传⼊labels=False即可只获取分位数的编号:
# 这些都是⻓度相等的桶。要根据样本分位数得到⼤⼩相等的桶,
# 使⽤qcut即可。传⼊labels=False即可只获取分位数的编号:
# Return quantile numbers
grouping = pd.qcut(frame.data1, 10, labels=False)
grouped = frame.data2.groupby(grouping)
grouped.apply(get_stats).unstack()
count max mean min
data1
0 100.0 1.670835 -0.010807 -3.399312
1 100.0 2.628441 -0.033573 -2.153545
2 100.0 2.527939 -0.149095 -2.925113
3 100.0 3.260383 0.072874 -2.315555
4 100.0 2.074345 -0.116594 -2.047939
5 100.0 2.184810 0.074563 -2.989741
6 100.0 2.089154 -0.033600 -2.084231
7 100.0 2.954439 -0.014457 -3.056990
8 100.0 2.735527 0.096532 -3.745356
9 100.0 2.377020 0.152483 -3.428254
Example: Filling Missing Values with Group-Specific Values
示例:⽤特定于分组的值填充缺失值
# 对于缺失数据的清理⼯作,有时你会⽤dropna将其替换掉,⽽有
# 时则可能会希望⽤⼀个固定值或由数据集本身所衍⽣出来的值去
# 填充NA值。这时就得使⽤fillna这个⼯具了。在下⾯这个例⼦
# 中,我⽤平均值去填充NA值:
# 示例:⽤特定于分组的值填充缺失值
# 对于缺失数据的清理⼯作,有时你会⽤dropna将其替换掉,⽽有
# 时则可能会希望⽤⼀个固定值或由数据集本身所衍⽣出来的值去
# 填充NA值。这时就得使⽤fillna这个⼯具了。在下⾯这个例⼦
# 中,我⽤平均值去填充NA值:
s = pd.Series(np.random.randn(6))
s[::2] = np.nan
s
s.fillna(s.mean())
0 0.433256
1 1.464753
2 0.433256
3 -0.194930
4 0.433256
5 0.029944
dtype: float64
假设你需要对不同的分组填充不同的值。⼀种⽅法是将数据分
# 组,并使⽤apply和⼀个能够对各数据块调⽤fillna的函数即可。
# 下⾯是⼀些有关美国⼏个州的示例数据,这些州⼜被分为东部和
# ⻄部:
# 假设你需要对不同的分组填充不同的值。⼀种⽅法是将数据分
# 组,并使⽤apply和⼀个能够对各数据块调⽤fillna的函数即可。
# 下⾯是⼀些有关美国⼏个州的示例数据,这些州⼜被分为东部和
# ⻄部:
states = ['Ohio', 'New York', 'Vermont', 'Florida',
'Oregon', 'Nevada', 'California', 'Idaho']
group_key = ['East'] * 4 + ['West'] * 4
data = pd.Series(np.random.randn(8), index=states)
data
Ohio -1.199705
New York 0.500468
Vermont -0.084207
Florida -0.145003
Oregon -0.382199
Nevada 0.588151
California 2.653656
Idaho -1.101910
dtype: float64
data[['Vermont', 'Nevada', 'Idaho']] = np.nan
data
data.groupby(group_key).mean()
我们可以⽤分组平均值去填充NA值:
# 我们可以⽤分组平均值去填充NA值:
fill_mean = lambda g: g.fillna(g.mean())
data.groupby(group_key).apply(fill_mean)
Ohio -1.199705
New York 0.500468
Vermont -0.084207
Florida -0.145003
Oregon -0.382199
Nevada 0.588151
California 2.653656
Idaho -1.101910
dtype: float64
fill_values = {'East': 0.5, 'West': -1}
fill_func = lambda g: g.fillna(fill_values[g.name])
data.groupby(group_key).apply(fill_func)
Example: Random Sampling and Permutation
示例:随机采样和排列
# 假设你想要从⼀个⼤数据集中随机抽取(进⾏替换或不替换)样
# 本以进⾏蒙特卡罗模拟(Monte Carlo simulation)或其他分析⼯
# 作。“抽取”的⽅式有很多,这⾥使⽤的⽅法是对Series使⽤
# sample⽅法:
# 示例:随机采样和排列
# 假设你想要从⼀个⼤数据集中随机抽取(进⾏替换或不替换)样
# 本以进⾏蒙特卡罗模拟(Monte Carlo simulation)或其他分析⼯
# 作。“抽取”的⽅式有很多,这⾥使⽤的⽅法是对Series使⽤
# sample⽅法:
# Hearts, Spades, Clubs, Diamonds
suits = ['H', 'S', 'C', 'D']
card_val = (list(range(1, 11)) + [10] * 3) * 4
base_names = ['A'] + list(range(2, 11)) + ['J', 'K', 'Q']
cards = []
for suit in ['H', 'S', 'C', 'D']:
cards.extend(str(num) + suit for num in base_names)

deck = pd.Series(card_val, index=cards)
现在我有了⼀个⻓度为52的Series,其索引包括牌名,值则是21
# 点或其他游戏中⽤于计分的点数(为了简单起⻅,我当A的点数
# 为1):
# 现在我有了⼀个⻓度为52的Series,其索引包括牌名,值则是21
# 点或其他游戏中⽤于计分的点数(为了简单起⻅,我当A的点数
# 为1):
deck[:13]
AH 1
2H 2
3H 3
4H 4
5H 5
6H 6
7H 7
8H 8
9H 9
10H 10
JH 10
KH 10
QH 10
dtype: int64
def draw(deck, n=5):
return deck.sample(n)
draw(deck)
get_suit = lambda card: card[-1] # last letter is suit
deck.groupby(get_suit).apply(draw, n=2)
deck.groupby(get_suit, group_keys=False).apply(draw, n=2)
Example: Group Weighted Average and Correlation
示例:分组加权平均数和相关系数
# 根据groupby的“拆分-应⽤-合并”范式,可以进⾏DataFrame
# 的列与列之间或两个Series之间的运算(⽐如分组加权平均)。
# 以下⾯这个数据集为例,它含有分组键、值以及⼀些权重值:
# 示例:分组加权平均数和相关系数
# 根据groupby的“拆分-应⽤-合并”范式,可以进⾏DataFrame
# 的列与列之间或两个Series之间的运算(⽐如分组加权平均)。
# 以下⾯这个数据集为例,它含有分组键、值以及⼀些权重值:
df = pd.DataFrame({'category': ['a', 'a', 'a', 'a',
'b', 'b', 'b', 'b'],
'data': np.random.randn(8),
'weights': np.random.rand(8)})
df
category data weights
0 a -0.608443 0.738078
1 a -0.340831 0.224993
2 a 0.197070 0.129218
3 a 1.129965 0.641297
4 b -1.078691 0.234486
5 b 0.261523 0.507843
6 b 0.473563 0.380462
7 b -0.939801 0.802412
# 然后可以利⽤category计算分组加权平均数:
grouped = df.groupby('category')
get_wavg = lambda g: np.average(g['data'], weights=g['weights'])
grouped.apply(get_wavg)
category
a 0.129411
b -0.360513
dtype: float64
close_px = pd.read_csv('examples/stock_px_2.csv', parse_dates=True,
index_col=0)
close_px.info()
close_px[-4:]
来做⼀个⽐较有趣的任务:计算⼀个由⽇收益率(通过百分数变
# 化计算)与SPX之间的年度相关系数组成的DataFrame。下⾯是
# ⼀个实现办法,我们先创建⼀个函数,⽤它计算每列和SPX列的
# 成对相关系数:
# 来做⼀个⽐较有趣的任务:计算⼀个由⽇收益率(通过百分数变
# 化计算)与SPX之间的年度相关系数组成的DataFrame。下⾯是
# ⼀个实现办法,我们先创建⼀个函数,⽤它计算每列和SPX列的
# 成对相关系数:
spx_corr = lambda x: x.corrwith(x['SPX'])
# 接下来,我们使⽤pct_change计算close_px的百分⽐变化:
rets = close_px.pct_change().dropna()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-62-11e2071548d0> in <module>()
1 # 接下来,我们使⽤pct_change计算close_px的百分⽐变化:
----> 2 rets = close_px.pct_change().dropna()

NameError: name 'close_px' is not defined

get_year = lambda x: x.year
by_year = rets.groupby(get_year)
by_year.apply(spx_corr)
# 当然,你还可以计算列与列之间的相关系数。这⾥,我们计算
# Apple和Microsoft的年相关系数:
by_year.apply(lambda g: g['AAPL'].corr(g['MSFT']))
# 当然,你还可以计算列与列之间的相关系数。这⾥,我们计算
# Apple和Microsoft的年相关系数:
by_year.apply(lambda g: g['AAPL'].corr(g['MSFT']))
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-63-3caa37fa4193> in <module>()
1 # 当然,你还可以计算列与列之间的相关系数。这⾥,我们计算
2 # Apple和Microsoft的年相关系数:
----> 3 by_year.apply(lambda g: g['AAPL'].corr(g['MSFT']))

NameError: name 'by_year' is not defined



Example: Group-Wise Linear Regression
示例:组级别的线性回归
# 顺着上⼀个例⼦继续,你可以⽤groupby执⾏更为复杂的分组统
# 计分析,只要函数返回的是pandas对象或标量值即可。例如,
# 我可以定义下⾯这个regress函数(利⽤statsmodels计量经济学
# 库)对各数据块执⾏普通最⼩⼆乘法(Ordinary Least
# Squares, OLS)回归:
# 示例:组级别的线性回归
# 顺着上⼀个例⼦继续,你可以⽤groupby执⾏更为复杂的分组统
# 计分析,只要函数返回的是pandas对象或标量值即可。例如,
# 我可以定义下⾯这个regress函数(利⽤statsmodels计量经济学
# 库)对各数据块执⾏普通最⼩⼆乘法(Ordinary Least
# Squares, OLS)回归:
import statsmodels.api as sm
def regress(data, yvar, xvars):
Y = data[yvar]
X = data[xvars]
X['intercept'] = 1.
result = sm.OLS(Y, X).fit()
return result.params
by_year.apply(regress, 'AAPL', ['SPX'])
by_year.apply(regress, 'AAPL', ['SPX'])

Original: https://blog.51cto.com/u_10055401/5482366
Author: 六mo神剑
Title: pyhton-聚合分组操作grouby

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/513609/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球