如何使用列标题作为填充值将Pandas数据帧从5列转换为1列?

2024-04-25 16:51:49 发布

您现在位置:Python中文网/ 问答频道 /正文

这是从一项调查中收集的数据,其中有一个单选按钮可从5个选项中选择一个。列中存储的是一个简单的1,作为表示它已被选中的标志。你知道吗

我想以一个列结束,列标题作为值。有人建议在我的数据帧上使用IDXMAX方法,但是当我查看文档时,我真的不知道如何应用它。不过,它看起来确实有用。。。你知道吗

我有一个数据帧:

 old = pd.DataFrame({'a FINSEC_SA' : [1,'NaN','NaN','NaN','NaN',1,'NaN'],
 'b FINSEC_A' : ['NaN',1,'NaN','NaN','NaN','NaN','NaN'],
 'c FINSEC_NO' : ['NaN','NaN',1,'NaN','NaN','NaN','NaN'],
 'd FINSEC_D' : ['NaN','NaN','NaN',1,'NaN','NaN',1],
 'e FINSEC_SD' : ['NaN','NaN','NaN','NaN',1,'NaN','NaN']})

enter image description here

我想以这样的数据帧结束:

new = pd.DataFrame({'Financial Security':['a FINSEC_SA','b FINSEC_A',
'c FINSEC_NO','d FINSEC_D','e FINSEC_SD','a FINSEC_SA','d FINSEC_D']})

enter image description here

我只有大约65k行数据,所以性能不是我的首选。我最感兴趣的是学习一个很好的方法来做到这一点-这是希望相当简单。如果idxmax很容易做到这一点,那就太好了。你知道吗


Tags: 数据方法no标题dataframe标志选项sa
3条回答

在下面的代码中,我创建了一个单独检查NaN的函数,正如我认为在实际数据中您将拥有的那样np.NaN公司而不是“NaN”(字符串)。可以相应地修改字符串

def isNaN(num):
    return num == 'NaN'

def getval(x):
    if not isNaN(x['a FINSEC_SA']) : return 'a FINSEC_SA'
    if not isNaN(x['b FINSEC_A']) : return 'b FINSEC_A'
    if not isNaN(x['c FINSEC_NO']) : return 'c FINSEC_NO'
    if not isNaN(x['d FINSEC_D']) : return 'd FINSEC_D'
    if not isNaN(x['e FINSEC_SD']) : return 'e FINSEC_SD'


old.apply(getval, axis=1)

这是可读的,但不是有效的答案。熔融功能可用于以更有效的方式获得相同的答案-

old['id'] = old.index
new = pd.melt(old, id_vars= 'id', var_name = 'Financial')
new = new[new['value'] != 'NaN'].drop('value', axis=1).sort_index(axis=0)

您可以直接使用idxmax后跟reset_index来实现这一点。你知道吗

df = old.idxmax(axis=1).reset_index().drop('index', axis=1).rename(columns={0:'Financial'})

print(df)

      Financial
0   a FINSEC_SA
1   b FINSEC_A
2   c FINSEC_NO
3   d FINSEC_D
4   e FINSEC_SD
5   a FINSEC_SA
6   d FINSEC_D

说明:
1idxmax跨列逐行选择最大值。
2drop删除不需要的列,然后删除duplicate值。
三。最后,我们根据需要rename列。你知道吗

idxmax只能用于数字。首先,我们需要将“NaN”(字符串)转换为np.NaN公司(数字值)。然后我们可以将每一列转换成一个数字系列:

old = old.replace('NaN', np.NaN)
old = old.apply(pd.to_numeric)

或者,您可以在一行中使用以下命令执行此操作:

old = old.apply(pd.to_numeric, errors='coerce')

最后,我们可以运行idxmax。您所要做的就是指定轴。轴=1表示每行中1的位置(最大值),轴=0表示每列中1的位置

new = old.idxmax(axis=1)

您可以在一行中运行代码(如果在此之后不需要旧代码的副本):

new = old.apply(pd.to_numeric, errors='coerce').idxmax(axis=1)

相关问题 更多 >