我有几个具有以下结构的DataFrame:
In [22]: arrays = [np.array(['A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2']),
....: np.array(['B1', 'B1', 'B2', 'B2', 'B1', 'B1', 'B2', 'B2']),
....: np.array(['C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2'])]
In [23]: df1 = pd.DataFrame(np.random.randint(10, size=(8, 4)), index=arrays)
In [24]: df1
Out[24]:
0 1 2 3
A1 B1 C1 2 7 3 4
C2 6 2 1 7
B2 C1 3 3 5 6
C2 9 6 3 6
A2 B1 C1 7 8 0 6
C2 6 3 1 6
B2 C1 9 3 8 2
C2 7 1 2 8
In [25]: df2 = pd.DataFrame(np.random.randint(10, size=(8, 4)), index=arrays)
In [26]: df2
Out[26]:
0 1 2 3
A1 B1 C1 7 2 5 2
C2 0 2 9 0
B2 C1 2 2 6 9
C2 4 6 3 8
A2 B1 C1 7 1 5 1
C2 6 2 2 6
B2 C1 5 8 1 6
C2 7 4 8 0
我想构建以下DataFrame。
max
是“0”子阵列中的最大值;
nth
是“2”子阵列中的第0个元素。
df1 df2
max nth max nth
A1 B1 6 3 7 5
B2 9 5 4 6
A2 B1 7 6 7 1
B2 9 2 7 6
我尝试df[0].groupby(level=[0, 1]).max()
来计算max
和df[2 or 3].groupby(level=[0, 1]).nth(0)
来计算nth
,但是使用索引值作为选择第2列或第3列的条件而使用连接。
答案 0 :(得分:1)
这是我的起点(与你的代码相同,不同的随机值):
0 1 2 3
A1 B1 C1 3 4 1 6
C2 6 3 4 5
B2 C1 8 3 5 1
C2 8 5 1 6
A2 B1 C1 8 7 0 6
C2 5 1 4 7
B2 C1 3 1 8 5
C2 7 1 7 8
df[0] = df.groupby(level=[0,1])[0].transform(max)
0 1 2 3
A1 B1 C1 6 4 1 6
C2 6 3 4 5
B2 C1 8 3 5 1
C2 8 5 1 6
A2 B1 C1 8 7 0 6
C2 8 1 4 7
B2 C1 7 1 8 5
C2 7 1 7 8
我找不到在第一级直接检查“1”的方法,所以我只是将其转换为带有reset_index
的colunn然后在它上面使用字符串方法相当容易。< / p>
df['one'] = df.reset_index().level_0.str.contains('1').values
df['nth'] = np.where( df.one, df[2], df[3] )
0 1 2 3 one nth
A1 B1 C1 6 4 1 6 True 1
C2 6 3 4 5 True 4
B2 C1 8 3 5 1 True 5
C2 8 5 1 6 True 1
A2 B1 C1 8 7 0 6 False 6
C2 8 1 4 7 False 7
B2 C1 7 1 8 5 False 5
C2 7 1 7 8 False 8
现在清理一下(其中一些可以提前完成,但我认为更清楚的是等到最后并将它们全部结合起来):
df.iloc[0::2,[0,-1]].reset_index(level=2,drop=True).rename(columns={0:'max'})
max nth
A1 B1 6 1
B2 8 5
A2 B1 8 6
B2 7 5
我不确定你是否也在询问concat,但这很简单:
pd.concat( [df1,df2], axis=1)
答案 1 :(得分:0)
我设法实现了我想要的解决方案:
In [55]: df = pd.DataFrame()
In [56]: for t, n in [(df1, 'df1'), (df2, 'df2')]:
....: t['nth'] = np.where(t.index.get_level_values(0).to_series().str.contains('1').values, t[2], t[3])
....: df[n, 'max'] = t[0].groupby(level=[0, 1]).max()
....: # reset_index() is required since nth() doesn't reduce number of index levels
....: df[n, 'nth'] = t['nth'].groupby(level=[0, 1]).nth(0).reset_index(level=2, drop=True)
In [57]: df
Out[57]:
(df1, max) (df1, nth) (df2, max) (df2, nth)
A1 B1 8 1 7 0
B2 6 3 9 3
A2 B1 7 2 7 3
B2 8 2 6 7
In [58]: df.columns = pd.MultiIndex.from_tuples(df.columns)
In [59]: df
Out[59]:
df1 df2
max nth max nth
A1 B1 8 1 7 0
B2 6 3 9 3
A2 B1 7 2 7 3
B2 8 2 6 7