【问题标题】:parse multiple series and rename header in python在python中解析多个系列并重命名标题
【发布时间】:2018-04-25 06:33:27
【问题描述】:

我的价格数据是这样的。(摘录)

import pandas as pd
df = pd.read_csv("price.csv", low_memory=False)
print(df.head())

   Unnamed: 0  233740 KS Equity  Unnamed: 2  233160 KS Equity   
0  2015-12-17           10330.0  2017-08-31           10460.0    
1  2015-12-18           10710.0  2017-09-01           10815.0    
2  2015-12-21           10720.0  2017-09-04           10835.0   
3  2015-12-22           10495.0  2017-09-05           10660.0   
4  2015-12-23           10425.0  2017-09-06           10535.0

如你所见

  1. 时间序列起点和终点相差两列和

  2. 有一个空单元格需要填写“date_23340 KS Equity”或其他内容。

我喜欢通过股票以有效的方式导入这个巨大的文件,最重要的是,将空单元格的名称更改为“date_equities 的名称”。我怎样才能把它分解成由日期和值组成的数据框?

【问题讨论】:

    标签: python pandas import


    【解决方案1】:

    首先通过移位列名创建Series,由第一个空格分割并附加Date,最后一个过滤器仅Unnamed索引值和rename列名:

    s = df.columns.to_series().shift(-1).str.split(n=1).str[0] + ' Date'
    s = s[s.index.str.startswith('Unnamed')]
    print (s)
    Unnamed: 0    233740 Date
    Unnamed: 2    233160 Date
    dtype: object
    
    df = df.rename(columns=s)
    print (df)
      233740 Date  233740 KS Equity 233160 Date  233160 KS Equity
    0  2015-12-17           10330.0  2017-08-31           10460.0
    1  2015-12-18           10710.0  2017-09-01           10815.0
    2  2015-12-21           10720.0  2017-09-04           10835.0
    3  2015-12-22           10495.0  2017-09-05           10660.0
    4  2015-12-23           10425.0  2017-09-06           10535.0
    

    如果需要从所有数据中创建 2 或 3 列,首先通过 split 创建 MultiIndex,然后调用 unstack

    df.columns = df.columns.str.split(n=1, expand=True)
    df = df.stack(0).reset_index(level=0, drop=True).rename_axis('val').reset_index()
    print (df)
          val        Date  KS Equity
    0  233160  2017-08-31    10460.0
    1  233740  2015-12-17    10330.0
    2  233160  2017-09-01    10815.0
    3  233740  2015-12-18    10710.0
    4  233160  2017-09-04    10835.0
    5  233740  2015-12-21    10720.0
    6  233160  2017-09-05    10660.0
    7  233740  2015-12-22    10495.0
    8  233160  2017-09-06    10535.0
    9  233740  2015-12-23    10425.0
    

    编辑:

    多个不同标题的解决方案:

    #create dummy data
    df1 = df.copy()
    df1.columns = ['Unnamed: 4','233 JP Equity','Unnamed: 6','235 JP Equity']
    df = df.join(df1)
    print (df)
       Unnamed: 0  233740 KS Equity  Unnamed: 2  233160 KS Equity  Unnamed: 4  \
    0  2015-12-17           10330.0  2017-08-31           10460.0  2015-12-17   
    1  2015-12-18           10710.0  2017-09-01           10815.0  2015-12-18   
    2  2015-12-21           10720.0  2017-09-04           10835.0  2015-12-21   
    3  2015-12-22           10495.0  2017-09-05           10660.0  2015-12-22   
    4  2015-12-23           10425.0  2017-09-06           10535.0  2015-12-23   
    
       233 JP Equity  Unnamed: 6  235 JP Equity  
    0        10330.0  2017-08-31        10460.0  
    1        10710.0  2017-09-01        10815.0  
    2        10720.0  2017-09-04        10835.0  
    3        10495.0  2017-09-05        10660.0  
    4        10425.0  2017-09-06        10535.0  
    
    s = df.columns.to_series().shift(-1) + ' Date'
    s = s[s.index.str.startswith('Unnamed')]
    print (s)
    Unnamed: 0    233740 KS Equity Date
    Unnamed: 2    233160 KS Equity Date
    Unnamed: 4       233 JP Equity Date
    Unnamed: 6       235 JP Equity Date
    dtype: object
    
    df = df.rename(columns=s)
    

    在list comprehension groupby by first number,同时创建dataetimeindex和concat。最后由stackunstack 重塑以删除NaNs:

    f = lambda x: x.split(' ',1)[1]
    df = pd.concat([x.set_index(x.columns[0]).rename(columns=f) for i, x 
                    in df.groupby(df.columns.str.split(n=1).str[0], axis=1)], 1).stack().unstack()
    print (df)
                JP Equity  KS Equity
    2015-12-17    10330.0    10330.0
    2015-12-18    10710.0    10710.0
    2015-12-21    10720.0    10720.0
    2015-12-22    10495.0    10495.0
    2015-12-23    10425.0    10425.0
    2017-08-31    10460.0    10460.0
    2017-09-01    10815.0    10815.0
    2017-09-04    10835.0    10835.0
    2017-09-05    10660.0    10660.0
    2017-09-06    10535.0    10535.0
    

    【讨论】:

    • 非常感谢@jezrael,在制作新的列标题之前你是正确的。它工作正常。但是,有一个小缓存,并非所有股票都以“KS Equity”结尾。数据中也有一些“JP Equity”,因此结果是,
    • val Date JP Equity KS Equity 0 069500 2013-01-02 NaN 27130.0 1 069660 2013-01-02 NaN 27110.0 2 091160 2013-01-02 NaN 16140.0 3 091170 2013-01-02 NaN 7540.0 4 091180 2013-01-02 NaN 20310.0
    • 也许我需要多一点帮助..非常感谢:)
    • @HannahLee - 当然,给我一些时间。
    • @HannahLee - 如果 KS EquityJP Equity 预期输出是什么? 3 列?
    【解决方案2】:

    如果您对文件第一行中 pandas 自动生成的标头不满意,您可以跳过它,告诉 pandas 不要生成标头并提供您自己的标头。 除此之外,您还可以选择要读入的列:

    df_1 = pd.read_csv("price.csv", usecols = [0,1], skiprows=1, header=['date', 'equity'])
    
    df_2 = pd.read_csv("price.csv", usecols = [2,3], skiprows=1, header=['date', 'equity'])
    

    【讨论】:

      猜你喜欢
      • 2017-09-13
      • 1970-01-01
      • 2019-07-26
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 2018-10-27
      相关资源
      最近更新 更多