【问题标题】:reshape a csv that has Nan pandas重塑具有 Nan pandas 的 csv
【发布时间】:2021-04-08 14:38:14
【问题描述】:

我有一个 csv 10k 行,26 列,例如:

pd.DataFrame({'col1':['a','a','b','b','a','a','b','b'],
              'col2':[12,2,12,1,13,2.2,14,2.1],
              'col3':[15,1.5,16,1.7,17,1.1,16.5,1],
              'col4':[np.nan,np.nan,17,2,18,2,18,2],})

每行有不同数量的 NaN,有些行包含所有 26 列的数据,其他行没有。

我想把它改成这样:

pd.DataFrame({'a1':[12,15,np.nan,13,17,18],'a2':[2,1.5,np.nan,2.2,1.1,2],
              'b1':[12,16,17,14,16.5,18],'b2':[1,1.7,2,2.1,1,2]})

我想ab的奇数实例为a1/b1,每个偶数实例为a2/b2,然后转换

我认为支点会起作用,但不能让它起作用

ls=['a1','a2','b1','b2']
df['n']=[ls[i%4] for i in range(df.shape[0])]    
df.iloc[:,1:5].pivot(columns='n')

有什么建议吗?

【问题讨论】:

    标签: pandas dataframe reshape


    【解决方案1】:

    这是我想出的解决方案

    设置种子 然后循环并将行附加到原始种子 并创建最终的df

    a1=df.iloc[0,1:4]
    a2=df.iloc[1,1:4]
    b1=df.iloc[2,1:4]
    b2=df.iloc[3,1:4]
    
    for i in range(4,df.shape[0]):
        if i%4==0: a1=a1.append(df.iloc[i,1:4])
        if i%4==1: a2=a2.append(df.iloc[i,1:4])
        if i%4==2: b1=b1.append(df.iloc[i,1:4])
        if i%4==3: b2=b2.append(df.iloc[i,1:4])
    pd.DataFrame({'a1':a1,'a2':a2,'b1':b1,'b2':b2}).reset_index(drop=True)
    

    【讨论】:

      【解决方案2】:

      作为对类似数据框但具有更多/更少行/列的完全动态解决方案,一种方法是 concat 具有列表理解的转置组,但为此您需要:

      1. get n - 每个子组的#行数
      2. 将索引更改为列名,为 .T 和 concat 做准备
      3. 创建单独转置的组

      n = int(pd.Series(df[df['col1'] == df['col1'].shift()].index).diff().max())
      df.index = pd.concat([pd.Series(cols)]*len(grp.unique()))
      grp = (df.groupby('col1').cumcount() // n)
      df_new = pd.concat([df[grp == i].T.iloc[1:] for i in range(grp.nunique())],
                         ignore_index=True)
      df_new
      Out[1]: 
          a1   b1    a2   b2
      0   12    2    12    1
      1   15  1.5    16  1.7
      2  NaN  NaN    17    2
      3   13  2.2    14  2.1
      4   17  1.1  16.5    1
      5   18    2    18    2
      

      【讨论】:

        【解决方案3】:

        我建议合并列,去掉不相关的列('variable'),然后创建一个新列,将col1 与索引的模数结合起来(得到 0 或 1)。 temp 列生成唯一列,以便可以进行透视。

        (
            df.melt("col1")
            .drop(columns="variable")
            .assign(
                col1=lambda df: df.col1 + (df.index % 2 + 1).astype(str),
                temp=lambda df: df.groupby("col1").cumcount(),
            )
            .pivot("temp", "col1", "value")
            .rename_axis(index=None, columns=None)
        )
        
        
             a1     a2       b1     b2
        0   12.0    2.0     12.0    1.0
        1   13.0    2.2     14.0    2.1
        2   15.0    1.5     16.0    1.7
        3   17.0    1.1     16.5    1.0
        4   NaN     NaN     17.0    2.0
        5   18.0    2.0     18.0    2.0
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-09
          • 2018-02-24
          • 2018-02-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-24
          相关资源
          最近更新 更多