将值转换为列

jde*_*esa 11 python pandas

对于模糊的问题名称,我们深表歉意,但我不确定如何调用此操作。

我有以下数据框:

import pandas as pd

df = pd.DataFrame({
    'A': [1, 3, 2, 1, 2],
    'B': [2, 1, 3, 2, 3],
    'C': [3, 2, 1, 3, 1],
})
print(df)
#    A  B  C
# 0  1  2  3
# 1  3  1  2
# 2  2  3  1
# 3  1  2  3
# 4  2  3  1
Run Code Online (Sandbox Code Playgroud)

这个数据代表一个“排行榜”的每个选项的,ABC为每一行。因此,举例来说,在排2C是最好的,然后A,然后B。我想构建“反向”的数据帧,其中,对于每一行,我有三列的123排名,具有的位置AB并且C是现在的数据。因此,对于上面的示例,结果将是:

out = pd.DataFrame({
    1: ['A', 'B', 'C', 'A', 'C'],
    2: ['B', 'C', 'A', 'B', 'A'],
    3: ['C', 'A', 'B', 'C', 'B'],
})
print(out)
#    1  2  3
# 0  A  B  C
# 1  B  C  A
# 2  C  A  B
# 3  A  B  C
# 4  C  A  B
Run Code Online (Sandbox Code Playgroud)

理想情况下,各行df应具有三个不同的值12并且3,但是可能有重复值的情况下(不是需要的是范围值,并要考虑)。如果可能的话,我想通过“连接”相同位置的选项名称,并在缺少位置使用空字符串或NaN来解决此问题。例如,使用以下输入:

df_bad = pd.DataFrame({'A': [1], 'B': [2], 'C': [2]})
print(df_bad)
#    A  B  C
# 0  1  2  2
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望获得以下输出:

out_bad = pd.DataFrame({1: ['A'], 2: ['BC'], 3: ['']})
print(out_bad)
#    1   2 3
# 0  A  BC
Run Code Online (Sandbox Code Playgroud)

另外,我可以选择仅获取其中一个值而不是并置。

我一直在寻找通过meltpivotpivot_table等功能,但我想不出来得到我想要的结果的方式。

ank*_*_91 8

您可以使用argsort

pd.DataFrame(df.columns.values[np.argsort(df.values)])
Run Code Online (Sandbox Code Playgroud)
   0  1  2
0  A  B  C
1  B  C  A
2  C  A  B
3  A  B  C
4  C  A  B
Run Code Online (Sandbox Code Playgroud)


WeN*_*Ben 7

这里有一种方法堆栈

df.stack().reset_index(level=1).set_index(0,append=True)['level_1'].unstack()
Out[89]: 
0  1  2  3
0  A  B  C
1  B  C  A
2  C  A  B
3  A  B  C
4  C  A  B
Run Code Online (Sandbox Code Playgroud)


use*_*203 6

您的第一个示例可以通过argsort和索引有效地解决。


m = np.argsort(df.to_numpy(), 1)

df.columns.to_numpy()[m]
Run Code Online (Sandbox Code Playgroud)

array([['A', 'B', 'C'],
       ['B', 'C', 'A'],
       ['C', 'A', 'B'],
       ['A', 'B', 'C'],
       ['C', 'A', 'B']], dtype=object)
Run Code Online (Sandbox Code Playgroud)

第二个示例有些棘手,但仍然是相同的想法,我将在不久后进行更新。


Qua*_*ang 6

其它的办法:

df = pd.DataFrame({
    'A': [1, 3, 2, 1, 2],
    'B': [2, 1, 3, 2, 3],
    'C': [3, 2, 1, 2, 1],
})

(df.stack()
   .reset_index()
   .groupby(['level_0',0])
   .level_1.apply(''.join)
   .unstack()
)
Run Code Online (Sandbox Code Playgroud)

输出:

0        1   2    3
level_0            
0        A   B    C
1        B   C    A
2        C   A    B
3        A  BC  NaN
4        C   A    B
Run Code Online (Sandbox Code Playgroud)


And*_* L. 5

对于重复排名的情况(例如第二个示例),使用pivotunstack在最后一步的任何解决方案都将失败。您需要pivot_tablecrosstab。正如您已经找到了使用的解决方案pivot_table。这是crosstab

df2 = df_bad.stack().reset_index(1, name='cols')
pd.crosstab(index=df2.index, columns=df2.cols, values=df2.level_1,
                             aggfunc=''.join).fillna('')

Out[171]:
cols   1   2
row_0
0      A  BC
Run Code Online (Sandbox Code Playgroud)

使用stackpivot

df.stack().reset_index(1, name='cols').pivot(columns='cols', values='level_1')

Out[131]:
cols  1  2  3
0     A  B  C
1     B  C  A
2     C  A  B
3     A  B  C
4     C  A  B
Run Code Online (Sandbox Code Playgroud)

  • 这是我认为最接近的解决方案,我可以在所有情况下都使用df2 = df.stack()。reset_index(1,name ='cols')使其正常工作。out = df2.pivot_table(index = df2.index,columns ='cols',values ='level_1',fill_value ='',aggfunc = np.sum)`。 (2认同)