我想知道有效且简洁的方法将滋扰列传递到pandas.DataFrame.groupby
的结果。我经常有列,我不想应用{ {1}}操作,但我确实希望值传播到结果。我想要做的一个例子如下所示
groupby
在此,我希望按import pandas as pd
import numpy as np
import random
import string
np.random.seed(43)
random.seed(43)
dates = pd.date_range("2015-01-01", "2017-01-02")
types = "AAABBCCCDDDDEEFFFFGG"
rtypes = list(types * len(dates))
rdates = dates.tolist() * len(types)
data = np.random.randn(len(rtypes))
info1 = [''.join(random.choice(string.ascii_uppercase) for _ in range(5))
for i in range(len(rtypes))]
info2 = [random.randint(100,1000) for i in range(len(rtypes))]
df = pd.DataFrame({"date": rdates, "category": rtypes, "vals": data,
"info1":info1, "info2": info2})
df = df.sort_values(["date", "category"]).reset_index(drop=True)
df.head()
category date info1 info2 vals
0 A 2015-01-01 BJWYE 990 0.257400
1 A 2015-01-01 ISQES 475 -0.867570
2 A 2015-01-01 KDEKE 214 1.683595
3 B 2015-01-01 TFOXR 203 0.575879
4 B 2015-01-01 HKTNF 992 -0.399677
和category
进行分组,并将一些功能应用于date
,但要传递vals
和info1
列。
这些是我找到的可能的解决方案,但两者看起来有点笨拙并且性能完全不同,这让我想知道是否有更高效或更简洁的解决方案。 我在此示例中应用info2
函数,但我更感兴趣的是可以为每个组返回1个值的函数,每个组的所有值或每个组的一些值。
存储索引
中所有想要的传递列rank
结果
%%timeit
(df.set_index(["date", "category", "info1", "info2"])
.groupby(axis=0, level=[0, 1]).rank().reset_index())
2.64 s ± 47.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
删除列并稍后再加入
sol1 = (df.set_index(["date", "category", "info1", "info2"])
.groupby(axis=0, level=[0, 1]).rank().reset_index())
sol1.sort_values(["date", "category"]).head()
date category info1 info2 vals
0 2015-01-01 A BJWYE 990 2.0
1 2015-01-01 A ISQES 475 1.0
2 2015-01-01 A KDEKE 214 3.0
3 2015-01-01 B TFOXR 203 2.0
4 2015-01-01 B HKTNF 992 1.0
答案 0 :(得分:2)
我认为你的事情太复杂了。您只需groupby
和rank
到vals
列。这会返回与原始pandas.Series
长度相同的df
,因此您只需将列设置为此。
df['vals'] = df.groupby(['date', 'category']).vals.rank()
category date info1 info2 vals
0 A 2015-01-01 BJWYE 990 2.0
1 A 2015-01-01 ISQES 475 1.0
2 A 2015-01-01 KDEKE 214 3.0
3 B 2015-01-01 TFOXR 203 2.0
4 B 2015-01-01 HKTNF 992 1.0