获取 Pandas 中每行 N Max/Min 个值的列名
Get column names for the N Max/Min values per row in Pandas
我正在尝试为每一行获取 max/min 值最多为 N 个值的列的名称。
给出这样的东西:
a b c d e
1.2 2 0.1 0.8 0.01
2.1 1.1 3.2 4.6 3.4
0.2 1.9 8.8 0.3 1.3
3.3 7.8 0.12 3.2 1.4
我可以用 idxmax(axis=1)
得到最大值,用 idxmin(axis=1)
得到最小值,但这只适用于顶部最大值和底部最小值,不适用于 N 值。
我想得到,如果用 N=2 调用:
a b c d e Max1 Max2 Min1 Min2
1.2 2.0 0.1 0.8 0.1 b a c e
2.1 1.1 3.2 4.6 3.4 d d b a
0.2 1.9 8.8 0.3 1.3 c b a d
3.3 7.8 0.1 3.2 1.4 b a c e
我知道我总是可以获取行数据,计算第 N 个值并按索引映射到列名列表,只是想知道是否有更好、更优雅的方法。
您可以使用 nlargest 和 nsmallest:
In [11]: res = df.apply(lambda x: pd.Series(np.concatenate([x.nlargest(2).index.values, x.nsmallest(2).index.values])), axis=1)
In [12]: res
Out[12]:
0 1 2 3
0 b a e c
1 d e b a
2 c b a d
3 b a c e
In [13]: df[["Max1", "Max2", "Min1", "Min2"]] = res
In [14]: df
Out[14]:
a b c d e Max1 Max2 Min1 Min2
0 1.2 2.0 0.10 0.8 0.01 b a e c
1 2.1 1.1 3.20 4.6 3.40 d e b a
2 0.2 1.9 8.80 0.3 1.30 c b a d
3 3.3 7.8 0.12 3.2 1.40 b a c e
如果 largest/smallest 和第二个 largest/smallest 值的顺序无关紧要,那么您可以使用 np.argpartition
.
N = 2 # Number of min/max values
u = np.argpartition(df, axis=1, kth=N).values
v = df.columns.values[u].reshape(u.shape)
maxdf = pd.DataFrame(v[:,-N:]).rename(columns=lambda x: f'Max{x+1}')
mindf = pd.DataFrame(v[:,:N]).rename(columns=lambda x: f'Min{x+1}')
pd.concat([df, maxdf, mindf], axis=1)
a b c d e Max1 Max2 Min1 Min2
0 1.2 2.0 0.10 0.8 0.01 b a e c
1 2.1 1.1 3.20 4.6 3.40 d e b a
2 0.2 1.9 8.80 0.3 1.30 b c a d
3 3.3 7.8 0.12 3.2 1.40 a b c e
我正在尝试为每一行获取 max/min 值最多为 N 个值的列的名称。
给出这样的东西:
a b c d e
1.2 2 0.1 0.8 0.01
2.1 1.1 3.2 4.6 3.4
0.2 1.9 8.8 0.3 1.3
3.3 7.8 0.12 3.2 1.4
我可以用 idxmax(axis=1)
得到最大值,用 idxmin(axis=1)
得到最小值,但这只适用于顶部最大值和底部最小值,不适用于 N 值。
我想得到,如果用 N=2 调用:
a b c d e Max1 Max2 Min1 Min2
1.2 2.0 0.1 0.8 0.1 b a c e
2.1 1.1 3.2 4.6 3.4 d d b a
0.2 1.9 8.8 0.3 1.3 c b a d
3.3 7.8 0.1 3.2 1.4 b a c e
我知道我总是可以获取行数据,计算第 N 个值并按索引映射到列名列表,只是想知道是否有更好、更优雅的方法。
您可以使用 nlargest 和 nsmallest:
In [11]: res = df.apply(lambda x: pd.Series(np.concatenate([x.nlargest(2).index.values, x.nsmallest(2).index.values])), axis=1)
In [12]: res
Out[12]:
0 1 2 3
0 b a e c
1 d e b a
2 c b a d
3 b a c e
In [13]: df[["Max1", "Max2", "Min1", "Min2"]] = res
In [14]: df
Out[14]:
a b c d e Max1 Max2 Min1 Min2
0 1.2 2.0 0.10 0.8 0.01 b a e c
1 2.1 1.1 3.20 4.6 3.40 d e b a
2 0.2 1.9 8.80 0.3 1.30 c b a d
3 3.3 7.8 0.12 3.2 1.40 b a c e
如果 largest/smallest 和第二个 largest/smallest 值的顺序无关紧要,那么您可以使用 np.argpartition
.
N = 2 # Number of min/max values
u = np.argpartition(df, axis=1, kth=N).values
v = df.columns.values[u].reshape(u.shape)
maxdf = pd.DataFrame(v[:,-N:]).rename(columns=lambda x: f'Max{x+1}')
mindf = pd.DataFrame(v[:,:N]).rename(columns=lambda x: f'Min{x+1}')
pd.concat([df, maxdf, mindf], axis=1)
a b c d e Max1 Max2 Min1 Min2
0 1.2 2.0 0.10 0.8 0.01 b a e c
1 2.1 1.1 3.20 4.6 3.40 d e b a
2 0.2 1.9 8.80 0.3 1.30 b c a d
3 3.3 7.8 0.12 3.2 1.40 a b c e