【问题标题】:Split values and renaming the columns with splitted value in pandas dataframe拆分值并在熊猫数据框中使用拆分值重命名列
【发布时间】:2021-02-08 11:38:56
【问题描述】:

所以现在我有一个 csv,数据看起来像这样

 email='abc@cde.com' AID=100200 PID=2500 NID=3950 
 email='def@ghk.com' AID=357156 PID=3544 NID=2688 
 email='testing@edu.uk' AID=385746 PID=6709 NID=2433
 ....

我想把这个系列拆分成一个数据框,最终表格如下:

     email           AID     PID     NID
   abc@cde.com     100200   2500   3950
   def@ghk.com     357156   3544   2688
   testing@edu.uk  385746   6709   2433

也就是说,我想要的如下:

  • 首先将系列分成 4 个,分隔符为 ' '
  • 然后使用分隔符“=”进一步拆分新数据框中的所有系列
  • 最后形成表格。第一部分 shd 是列名,第二部分 shd 保留为值

我所做的是:

# Assume the df as newdf 
import pandas as pd

excel_test = pd.read_csv('filename')
newdf = excel_test.iloc[:,1].str.split(' ', expand=True)

for x in range(1, len(newdf.columns) -1):
    newdf.iloc[:,x] = newdf.iloc[:,x].str.split('=', expand=True)[1]
    new_column_name = newdf.iloc[:,x].str.split('=', expand=True)[0]
    newdf.rename(columns={newdf.columns[x]: new_column_name}, inplace=True)

print(newdf)

在这个脚本中,我得到了值,但是,我得到了一个错误:
TypeError: 'Series' 对象是可变的,因此它们不能被散列

当我也尝试更改列名时

那么问题来了:

  1. 在这种情况下如何同时更改列名?
  2. 我有一种感觉,for循环可以换成类似str的函数,这样可以让代码更干净,更有条理。有没有其他方法可以做到这一点?

感谢您的帮助!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    Idea 正在使用具有列表和字典理解的列 col 以及由split() 和由=split('=') 的空格分割值:

    df = pd.read_csv('filename', names=['col'])
    
    print (df)
                                                     col
    0   email='abc@cde.com' AID=100200 PID=2500 NID=3950
    1   email='def@ghk.com' AID=357156 PID=3544 NID=2688
    2  email='testing@edu.uk' AID=385746 PID=6709 NID...
    
    
    df = pd.DataFrame([dict(y.split('=') for y in x.split()) for x in df['col']])
    print (df)
                  email     AID   PID   NID
    0     'abc@cde.com'  100200  2500  3950
    1     'def@ghk.com'  357156  3544  2688
    2  'testing@edu.uk'  385746  6709  2433
    

    另一个想法是使用\s+|= 分隔符以空格或= 分隔:

    df = pd.read_csv('filename', sep="\s+|=", header=None, engine='python')
        
    print (df)
           0                 1    2       3    4     5    6     7
    0  email     'abc@cde.com'  AID  100200  PID  2500  NID  3950
    1  email     'def@ghk.com'  AID  357156  PID  3544  NID  2688
    2  email  'testing@edu.uk'  AID  385746  PID  6709  NID  2433
    

    然后通过取消配对第一行来选择对列并设置列名:

    cols = df.iloc[0, ::2]
    df = df.iloc[:, 1::2]
    df.columns = cols
    print (df)
    0             email     AID   PID   NID
    0     'abc@cde.com'  100200  2500  3950
    1     'def@ghk.com'  357156  3544  2688
    2  'testing@edu.uk'  385746  6709  2433
    

    最后提到的@Suhas Mucherla(谢谢)可以通过Series.str.strip 删除''

    df['email']=df['email'].str.strip("'")
    

    【讨论】:

    • 太棒了!此外,' 的电子邮件列应该被剥离
    【解决方案2】:

    你可以这样做:

    df=pd.read_csv("/home/neureol/test2.csv",delimiter=' ',header=None).dropna(axis=1)
    df.columns=[str(i).split('=')[0] for i in df.loc[0,:]]
    df=df.replace('|'.join(df.columns+"="),'',regex=True)
    df['email']=df['email'].str.strip("'")
    
    df
    Out[47]: 
                email     AID   PID   NID
    0     abc@cde.com  100200  2500  3950
    1     def@ghk.com  357156  3544  2688
    2  testing@edu.uk  385746  6709  2433
    

    【讨论】:

      【解决方案3】:

      你可以使用:

      import pandas as pd
      
      df=pd.read_csv("data.csv",delimiter=' ',header=None).dropna(axis=1)
      
      dict1 = {}
      for row in df.values.tolist():
          for item in row:
              _row = item.replace("'","").split("=")
              if _row[0] not in dict1.keys():
                  dict1[_row[0]] = [_row[1]]
              else:
                  dict1[_row[0]] = dict1[_row[0]] + [_row[1]]
      
      df = pd.DataFrame(dict1)
      print(df)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-28
        • 2013-06-23
        • 2019-10-26
        • 1970-01-01
        • 2020-02-19
        相关资源
        最近更新 更多