【问题标题】:Rearranging dataframe dimensions重新排列数据框维度
【发布时间】:2023-04-04 13:57:01
【问题描述】:

我有一个包含很多列的 df:

   date  risk lev   chemical  weight    date    risk lev   chemical  weight
 15-5-16   5         Potasium   5mg    15-5-16      3       Sodium     7 mg 
 14-5-16   6         Potasium   10mg   14-5-16      2       Sodium     2 mg  

我想重新排列一下,让每4列分成一个新行,比如df是这样的:

   date  risk lev   chemical  weight
 15-5-16      5      Potasium   5mg   
 15-5-16      3       Sodium    7mg  
 14-5-16      6      Potasium   10mg   
 14-5-16      2       Sodium    2mg

抱歉,我没有包括我的尝试,但这是我第一次解决这个问题,不知道如何继续

【问题讨论】:

  • 列名是否重复?
  • 是的,它们是重复的。

标签: pandas duplicates multiple-columns reshape lreshape


【解决方案1】:

首先删除具有列名的重复项,然后使用pd.lreshapedict 创建的dict comprehension

s = df.columns.to_series()
df.columns = s.add(s.groupby(s).cumcount().astype(str))
print (df)
     date0  risk lev0 chemical0 weight0    date1  risk lev1 chemical1 weight1
0  15-5-16          5  Potasium     5mg  15-5-16          3    Sodium     7mg
1  14-5-16          6  Potasium    10mg  14-5-16          2    Sodium     2mg


cols = ['date','risk lev','chemical','weight']
d = {x:df.columns[df.columns.str.startswith(x)].tolist() for x in cols}
print (d)
{'date': ['date0', 'date1'], 
 'weight': ['weight0', 'weight1'], 
 'risk lev': ['risk lev0', 'risk lev1'], 
 'chemical': ['chemical0', 'chemical1']}

df = pd.lreshape(df, d)
print (df)
      date weight  risk lev  chemical
0  15-5-16    5mg         5  Potasium
1  14-5-16   10mg         6  Potasium
2  15-5-16    7mg         3    Sodium
3  14-5-16    2mg         2    Sodium

【讨论】:

    【解决方案2】:

    首先去掉列名中的重复项:

    In [248]: df
    Out[248]:
          date  risk lev  chemical weight   date.1  risk lev.1 chemical.1 weight.1
    0  15-5-16         5  Potasium    5mg  15-5-16           3     Sodium     7 mg
    1  14-5-16         6  Potasium   10mg  14-5-16           2     Sodium     2 mg
    

    现在我们可以使用pd.lreshape

    In [249]: d = {
         ...:     'chemical': ['chemical','chemical.1'],
         ...:     'weight':['weight','weight.1'],
         ...:     'date':['date','date.1'],
         ...:     'risk lev': ['risk lev','risk lev.1']
         ...: }
    
    In [250]: pd.lreshape(df, d)
    Out[250]:
       chemical weight     date  risk lev
    0  Potasium    5mg  15-5-16         5
    1  Potasium   10mg  14-5-16         6
    2    Sodium   7 mg  15-5-16         3
    3    Sodium   2 mg  14-5-16         2
    

    【讨论】:

      【解决方案3】:

      pd.wide_to_long 更有效地解决了这个问题。您必须先在每列的末尾放置一个数字。

      df.columns = [col + str(i//4 + 1) for i, col in enumerate(df.columns)]
      
      pd.wide_to_long(df.reset_index(), 
                      stubnames=['date', 'risk lev', 'chemical', 'weight'], 
                      i='index', 
                      j='dropme').reset_index(drop=True)
      
            date  risk lev  chemical weight
      0  15-5-16         5  Potasium    5mg
      1  14-5-16         6  Potasium   10mg
      2  15-5-16         3    Sodium    7mg
      3  14-5-16         2    Sodium    2mg
      

      【讨论】:

      • 现在我正在度假,因此无法使用替代解决方案编辑 lreshape 答案。很抱歉。
      猜你喜欢
      • 2022-06-12
      • 1970-01-01
      • 2012-08-11
      • 2021-03-13
      • 2017-08-12
      • 2017-08-03
      • 2020-02-24
      • 2013-01-12
      • 2022-06-13
      相关资源
      最近更新 更多