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

Python 如何使用列标题作为填充值将Panda数据帧从5列转换为1列?,python,pandas,dataframe,transformation,Python,Pandas,Dataframe,Transformation,这是从一项调查中收集的数据,其中有一个单选按钮可从5个选项中选择1个。列中存储的是一个简单的1,作为表示它已被选中的标志 我希望以一个列结束,列标题作为值。有人建议在我的数据框架上使用IDXMAX方法,但当我查看文档时,我真的不知道如何应用它。它看起来确实会对这个有用,尽管 我有一个数据帧: old = pd.DataFrame({'a FINSEC_SA' : [1,'NaN','NaN','NaN','NaN',1,'NaN'], 'b FINSEC_A' : ['NaN',1,'NaN

这是从一项调查中收集的数据,其中有一个单选按钮可从5个选项中选择1个。列中存储的是一个简单的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']})

我希望以这样的数据帧结束:

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']})


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

您可以直接使用
idxmax
,然后使用
reset\u 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
说明:
1. <代码>idxmax跨列逐行选择最大值
2. <代码>删除删除不需要的列,然后删除重复的值。

3.最后,我们根据需要重命名列

您可以直接使用
idxmax
然后使用
reset\u 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
说明:
1. <代码>idxmax跨列逐行选择最大值
2. <代码>删除删除不需要的列,然后删除重复的值。

3.最后,我们根据需要重命名列

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。您所要做的就是指定轴。axis=1表示每行中1(最大值)的位置,axis=0表示每列中1的位置

new = old.idxmax(axis=1)
您可以在一行中运行代码(如果在此之后不需要旧代码的副本):


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。您所要做的就是指定轴。axis=1表示每行中1(最大值)的位置,axis=0表示每列中1的位置

new = old.idxmax(axis=1)
您可以在一行中运行代码(如果在此之后不需要旧代码的副本):


在下面的代码中,我创建了一个单独检查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)

在下面的代码中,我创建了一个单独检查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)

虽然这个答案是值得称赞的,而且行之有效,但它也有不足之处。例如,一个问题是如何处理附加列。此解决方案需要更改代码,其他解决方案则不需要。另一个原因是,它与使用
pandas
primitives的解决方案相比,时间安排可能很差。虽然这是一项值得信赖的工作,而且行之有效,但它也有不足之处。例如,一个问题是如何处理附加列。此解决方案需要更改代码,其他解决方案则不需要。另一个原因是,它与使用
pandas
原语的解决方案相比,可能计时不及时。我希望您将原始答案保留在中,以便进行比较,而不是对其进行编辑。我相信很多人都知道尝试不同方法的价值,所以可以说这会增加问题的多样性。我后来意识到这是错误的答案。我只是简单地叠加数据,以获得原始列名。但是,答案需要基于非na值的列名。我希望您将原始答案保留在中以供比较,而不是编辑它。我相信很多人都知道尝试不同方法的价值,所以可以说这会增加问题的多样性。我后来意识到这是错误的答案。我只是简单地叠加数据,以获得原始列名。但是,答案需要基于非na值的列名。不同答案的范围,可能来自不同体验水平的用户,值得一读,因为它显示了许多复杂程度的方法。感谢所有回答的人。在创建上面的第一个数据帧时,我没有意识到我在做什么,将“NaN”创建为字符串,而不是数字值。显然,按照我的数据实际情况创建它会更好-使用正确的方式。。。在这一点上,我对python有点陌生,只是想弄明白一些事情。不同答案的范围,可能来自不同体验级别的用户,这是对完整阅读的回报,因为它显示了许多复杂程度的方法。感谢所有回答的人。在创建上面的第一个数据帧时,我没有意识到我在做什么,将“NaN”创建为字符串,而不是数字值。显然,按照我的数据实际情况创建它会更好-使用正确的方式。。。在这一点上,我对python有点陌生,只是想弄明白一些事情。