Python 熊猫:将一行的多个列连接到多行(1:n)

Python 熊猫:将一行的多个列连接到多行(1:n),python,pandas,dataframe,Python,Pandas,Dataframe,我有一个数据框架,其中有很多键/值列,而键和值是分开的列 import pandas as pd values = [['John', 'somekey1', 'somevalue1', 'somekey2', 'somevalue2']] df = pd.DataFrame(values, columns=['name', 'key1', 'value1', 'key2', 'value2']) 备注:原始数据将有更多前面的列,而不仅仅是名称。它不仅仅有两个键/值列 我想要达到的是这样的结

我有一个数据框架,其中有很多键/值列,而键和值是分开的列

import pandas as pd

values = [['John', 'somekey1', 'somevalue1', 'somekey2', 'somevalue2']]
df = pd.DataFrame(values, columns=['name', 'key1', 'value1', 'key2', 'value2'])
备注:原始数据将有更多前面的列,而不仅仅是名称。它不仅仅有两个键/值列

我想要达到的是这样的结果:

values = [
    ['John', 'somekey1', 'somevalue1'],
    ['John', 'somekey2', 'somevalue2']
]
df = pd.DataFrame(values, columns=['name', 'key', 'value'])
在那里,我想把所有键/值列连接到一个列表或字典中,然后分解该列表/dict。我在pd.melt上找到了它,但我的问题是,我事先不知道确切的id\u var列。因此,我尝试了pd.Series.stack,它为key/value列提供了正确的结果,但缺少原始数据中的其他列。有什么想法吗?以下是我尝试过的:

# generates: [(somekey1, somevalue1), (somekey2, somevalue2)]
df['pairs'] = df.apply(lambda row: [(row['key1'],row['value1']), (row['key2'], row['value2'])], axis=1)
# unstacks the list, but drops all other columns
df['pairs'].apply(pd.Series).stack().reset_index(drop=True).to_frame('pairs')
IIUC宽到长


我想到的是:

common = ['name'] # Add more columns, if needed
# Alternatively:
common = df.loc[:, :'name'].columns # Everything up to 'name'
result = pd.concat([df.loc[:, common + ['key1', 'value1']],
                    df.loc[:, common + ['key2', 'value2']]])

result['key'] = np.where(result['key1'].isnull(),
                         result['key2'], result['key1'])
result['value'] = np.where(result['value1'].isnull(),
                           result['value2'], result['value1'])
result.drop(['value1', 'value2', 'key1', 'key2'], axis=1, inplace=True)
#   name       key       value
#0  John  somekey1  somevalue1
#0  John  somekey2  somevalue2

从来没有听说过宽到长。酷。@DyZ-yep,这个函数不太流行,还有一个叫做lreshape:-非常好的解决方案。谢谢现在我明白了宽和长的区别。@Matthias-yes:-yw~高兴吗coding@Matthias添加一个ID可以作为df.reset\u索引完成
common = ['name'] # Add more columns, if needed
# Alternatively:
common = df.loc[:, :'name'].columns # Everything up to 'name'
result = pd.concat([df.loc[:, common + ['key1', 'value1']],
                    df.loc[:, common + ['key2', 'value2']]])

result['key'] = np.where(result['key1'].isnull(),
                         result['key2'], result['key1'])
result['value'] = np.where(result['value1'].isnull(),
                           result['value2'], result['value1'])
result.drop(['value1', 'value2', 'key1', 'key2'], axis=1, inplace=True)
#   name       key       value
#0  John  somekey1  somevalue1
#0  John  somekey2  somevalue2