[英]Create a python dataframe using a conditional groupby
我有以下數據:
year code value
2003 A 12
2003 B 11
2003 C 12
2004 A 14
2004 B 15
2004 C 13
2004 E 16
2005 A 9
2005 B 18
2005 C 16
2005 F 8
2005 G 19
我只想保留每年存在的代碼。
從上面的數據框中,我需要提取年份中出現過代碼的所有行(2003、2004、2005)。 這意味着我應該有一個新的df,其中包含9行,分別用於代碼A,B和C。我嘗試使用groupby和isin(),但無法准確獲得所需的內容。
沒有groupby
df.set_index(['year','code']).unstack().dropna(axis=1).stack().reset_index()
Out[528]:
year code value
0 2003 A 12.0
1 2003 B 11.0
2 2003 C 12.0
3 2004 A 14.0
4 2004 B 15.0
5 2004 C 13.0
6 2005 A 9.0
7 2005 B 18.0
8 2005 C 16.0
我相信您需要按isin
過濾,但是如果要動態獲取所有年份的所有值,請使用reduce
:
s = df.groupby('year')['code'].apply(list)
from functools import reduce
a = reduce(lambda x, y: set(x) & set(y), s)
print (list(a))
['C', 'A', 'B']
df = df[df['code'].isin(list(a))]
print (df)
year code value
0 2003 A 12
1 2003 B 11
2 2003 C 12
3 2004 A 14
4 2004 B 15
5 2004 C 13
7 2005 A 9
8 2005 B 18
9 2005 C 16
您也可以嘗試基於query
的方法。
df.query("2005 >= year >= 2003 and code in ['A', 'B', 'C']")
year code value
0 2003 A 12
1 2003 B 11
2 2003 C 12
3 2004 A 14
4 2004 B 15
5 2004 C 13
7 2005 A 9
8 2005 B 18
9 2005 C 16
你可以用
選項1
In [647]: codes = pd.crosstab(df.year, df.code).replace({0: np.nan}).dropna(axis=1).columns
In [648]: df.query('code in @codes')
Out[648]:
year code value
0 2003 A 12
1 2003 B 11
2 2003 C 12
3 2004 A 14
4 2004 B 15
5 2004 C 13
7 2005 A 9
8 2005 B 18
9 2005 C 16
選項2
In [657]: codes = df.groupby(['year', 'code']).size().unstack().dropna(axis=1).columns
In [658]: df[df.code.isin(codes)]
Out[658]:
year code value
0 2003 A 12
1 2003 B 11
2 2003 C 12
3 2004 A 14
4 2004 B 15
5 2004 C 13
7 2005 A 9
8 2005 B 18
9 2005 C 16
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.