从单行数据框创建多行数据框

时间:2018-06-27 16:48:49

标签: python python-3.x pandas dataframe

我的数据框是具有N列的单行:

   col1    col2    col3    col4   col5    col6   col7     col8    col9      
0  NBA      Mens    Sports  LAL    Lakers   BOS   Celtics    SAS    Spurs    

我正在寻找的输出是一个新的数据帧,如下所示,这里前三列的值对于所有行都是相同的。但是,对于新数据帧中的每一行,此新数据帧中的col4和col5值都被上述DF列值col4,col5和col6,col 7和col8,col9等所取代

    col1    col2    col3    col4    col5
0   NBA    Mens   Sports    LAL     Lakers
1   NBA    Mens   Sports    BOS     Celtics
2   NBA    Mens   Sports    SAS     Spurs

我的代码:

将单行转换为ndarray

import pandas as pd
df = pd.read_csv('df_info.txt', sep=",", header=0)
vallist=df.as_matrix()[0]

创建一个存储值的Dict

dict={}
n=4
varlist1=[]
for i in range(len(vallist)):
    if(n<=9):
        dict[i]={}
        print(vallist[n],vallist[n+1])
        dict[i]['col1']=vallist[0]
        dict[i]['col2']=vallist[1]
        dict[i]['col3']=vallist[2]
        dict[i]['col4']=vallist[n]
        dict[i]['col5']=vallist[n+1]
        n+=2

将字典导入数据框

df2=pd.DataFrame.from_dict(dict)
df2.transpose()

我正在获得所需的结果,但我不相信,正在寻找更多的pythonic和panda方法来实现这一目标。

2 个答案:

答案 0 :(得分:3)

我们可以使用理解力和巧妙的拆包功能。

  • 对于每一行,我都获取前三个值,其余的

    a, b, c, *x in df.values
    
  • 然后我将x[::2]x[1::2]

    压缩在一起,循环浏览其余的每一对。
  • 使用renameadd_prefix来确定列名。

  • 这可以概括为前三列之后的任意数量的对。

pd.DataFrame([
    [a, b, c, d, e]
    for a, b, c, *x in df.values
    for d, e in zip(x[::2], x[1::2])
]).rename(columns=lambda x: x + 1).add_prefix('col')

  col1  col2    col3 col4     col5
0  NBA  Mens  Sports  LAL   Lakers
1  NBA  Mens  Sports  BOS  Celtics
2  NBA  Mens  Sports  SAS    Spurs

答案 1 :(得分:1)

结合使用numpy.repeatitertools.chain和一些字典知识:

import numpy as np
from itertools import chain

df['abbr_combined'] = list(zip(df.col4, df.col6, df.col8))
df['team_combined'] = list(zip(df.col5, df.col7, df.col9))

lens = df['team_combined'].map(len)

res = pd.DataFrame({**{col: np.repeat(df[col], lens) for col in ('col1', 'col2', 'col3')},
                    **{col: list(chain.from_iterable(df[name])) for col, name in
                            zip(('col4', 'col5'), ('abbr_combined', 'team_combined'))}})

print(res)

  col1  col2    col3 col4     col5
0  NBA  Mens  Sports  LAL   Lakers
0  NBA  Mens  Sports  BOS  Celtics
0  NBA  Mens  Sports  SAS    Spurs