[英]Determining when order of a set of columns changes in pandas dataframe
我有一个非常大的csv文件,其结构如下:
a1 b1 c1 a2 b2 c2 a3 b3 c3 ..... a999 b999 c999
0 5 4 2 3 2 2 6 7 9 ....................
1 2 1 4 4 6 9 3 5 9 ....................
.
.
我想做的是将A,b和c中的N列分组,并检查每行中该集合的最大值(argmax)的索引何时更改。
因此,在上面的示例中,对于N = 3,a1,b1,c1是行0中的第一组,argmax为0,第二组为a2,b2,c2和argmax仍为0,第三组为a3,b3, c3,但现在argmax为2。我确实在寻找一个解析整个csv文件并返回[c3,c1]的脚本。 c3是因为那是argmax在第0行发生变化的地方,而c1是因为argmax在第1行没有发生变化,但是c1是该集合中的最大值。
我现在通过使用两个for循环及其缓慢来执行此操作,并且看起来非常丑陋,是否有更好的pandas pythonic方式来执行此操作? 我觉得一定有。
您可以groupby
列集合,并使用.idxmax
找到其中最大每一组内发生的列。 您可以找到第一个字母更改的位置(如果有的话)以获取列表。
n = 3
df2 = df.groupby([x//n for x in range(len(df.columns))], axis=1).idxmax(1)
mask = df2.applymap(lambda x: x[0]) # Case of 1-letter column prefix
## If possibility of words with different length ending in digits try
# import string
# mask = df2.applymap(lambda x: x.strip(string.digits))
df2.lookup(df2.index,
(mask.ne(mask.shift(-1, axis=1)).idxmax(1)+1) % (len(mask.columns))).tolist()
print(df)
a1 b1 c1 a2 b2 c2 a3 b3 c3
0 5 4 2 3 2 2 6 7 9
1 2 1 4 4 6 9 3 5 9
2 2 1 4 10 6 9 3 5 9
3 2 1 4 1 6 9 3 10 9
n = 3
df2 = df.groupby([x//n for x in range(len(df.columns))], axis=1).idxmax(1)
print(df2)
# 0 1 2
#0 a1 a2 c3
#1 c1 c2 c3
#2 c1 a2 c3
#3 c1 c2 b3
mask = df2.applymap(lambda x: x[0])
df2.lookup(df2.index, (mask.ne(mask.shift(-1, axis=1)).idxmax(1)+1) % (len(mask.columns))).tolist()
#['c3', 'c1', 'a2', 'b3']
我试图使代码尽可能简单。 您可以通过切片的列名称来转换数据框和分组:
df = df.T.reset_index()
idx = df.groupby(df['index'].str.slice(1,2)).idxmax()
输出:
0 1
index
1 0 2
2 3 5
3 8 8
这意味着对于第0行,组1的最大值在索引0处,最大组2在索引3处(或者0是您采用的mod 3),组3的最大值在索引8处(如果您是mod 2,则为2采取mod 3)。 第1行的读数相同:)
如果您需要实际的列名:
df.columns[idx.values.flatten(order='F')]
输出:
['a1', 'a2', 'c3', 'c1', 'c2', 'c3']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.