【问题标题】:How to split data to multiple rows in pandas on one condition?如何在一种条件下将数据拆分为 pandas 中的多行?
【发布时间】:2019-02-06 01:33:24
【问题描述】:

我在以下数据框中的数据为:-

id name value year quarter 
1 an     2.3  2012 1
2 yu     3.5  2012 2
3 ij     3.1  2013 4
4 ij     2.1  2013 1

要转换为以下数据框,即从季度获取月份并将行拆分为 3。

id name value year quarter month
1 an     2.3  2012 1       01
1 an     2.3  2012 1       02
1 an     2.3  2012 1       03
2 yu     3.5  2012 2       04
2 yu     3.5  2012 2       05
2 yu     3.5  2012 2       06
3 ij     3.1  2013 4       10  
3 ij     3.1  2013 4       11
3 ij     3.1  2013 4       12
4 ij     2.1  2013 1       01
4 ij     2.1  2013 1       02
4 ij     2.1  2013 1       03

【问题讨论】:

  • 四分之一的拼写会增加编辑的大量流失。我建议我们在示例数据中将其保留为“quater”以匹配所有提交。

标签: python pandas date


【解决方案1】:

使用 reindexpd.to_datetime ,我们为每个子组添加 cumcount

df=df.reindex(df.index.repeat(3))
df['Month']=pd.to_datetime(df[['year','quarter']].astype(str).apply('Q'.join,1)).dt.month+df.groupby(level=0).cumcount()
df
Out[1258]: 
   id name  value  year  quarter  Month
0   1   an    2.3  2012        1      1
0   1   an    2.3  2012        1      2
0   1   an    2.3  2012        1      3
1   2   yu    3.5  2012        2      4
1   2   yu    3.5  2012        2      5
1   2   yu    3.5  2012        2      6
2   3   ij    3.1  2013        4     10
2   3   ij    3.1  2013        4     11
2   3   ij    3.1  2013        4     12

【讨论】:

    【解决方案2】:

    首先,在当前 DataFrame 中创建一个包含每个季度的月份范围的 DataFrame:

    m = pd.DataFrame([range(i*3-2, 3*i+1) for i in df.quater], index=df.quater)
    

             0   1   2
    quater
    1        1   2   3
    2        4   5   6
    4       10  11  12
    

    现在加入并堆叠:

    df.set_index('quater').join(m.stack().reset_index(1, drop=True).rename('month'))
    

            id name  value  year  month
    quater
    1        1   an    2.3  2012      1
    1        1   an    2.3  2012      2
    1        1   an    2.3  2012      3
    2        2   yu    3.5  2012      4
    2        2   yu    3.5  2012      5
    2        2   yu    3.5  2012      6
    4        3   ij    3.1  2013     10
    4        3   ij    3.1  2013     11
    4        3   ij    3.1  2013     12
    

    【讨论】:

      【解决方案3】:

      你可以重复使用

      In [360]: dff = df.loc[df.index.repeat(3)]
      
      In [362]: dff.assign(month = dff.quater.sub(1) * 3 + dff.groupby('quater').cumcount() + 1)
      Out[362]:
         id name  value  year  quater  month
      0   1   an    2.3  2012       1      1
      0   1   an    2.3  2012       1      2
      0   1   an    2.3  2012       1      3
      1   2   yu    3.5  2012       2      4
      1   2   yu    3.5  2012       2      5
      1   2   yu    3.5  2012       2      6
      2   3   ij    3.1  2013       4     10
      2   3   ij    3.1  2013       4     11
      2   3   ij    3.1  2013       4     12
      

      【讨论】:

      • 我不确定,但如果我有另一个数据,年份为 2013 年和 quater 为 1,则会产生不正确的结果
      【解决方案4】:

      创建一个季度到月的数据框以进行合并

      q2m = pd.DataFrame([
          [(m - 1) // 3 + 1, m] for m in range(1, 13)],
          columns=['quarter', 'month']
      )
      
      df.merge(q2m)
      
         id name  value  year  quarter  month
      0   1   an    2.3  2012        1      1
      1   1   an    2.3  2012        1      2
      2   1   an    2.3  2012        1      3
      3   2   yu    3.5  2012        2      4
      4   2   yu    3.5  2012        2      5
      5   2   yu    3.5  2012        2      6
      6   3   ij    3.1  2013        4     10
      7   3   ij    3.1  2013        4     11
      8   3   ij    3.1  2013        4     12
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-10-23
        • 2018-07-24
        • 2019-05-11
        • 1970-01-01
        • 2019-05-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多