【问题标题】:python split the column values of a dataframepython拆分数据框的列值
【发布时间】:2021-10-05 03:37:00
【问题描述】:

我正在研究 python 并且是新手。我有一个数据框

Date           Emailable    Lost_Fans   New_Fans    Country
12-10-2020      121134                                 JP
06-11-2020      120859         350         75          JP
18-12-2020      101857        19128       126          JP
29-01-2021      105760         5029      8932          JP
16-02-2021      115437         1279      10956         JP
01-03-2021      115512          517       592          JP    
12-07-2021      137546         18074     40108         JP
11-08-2021      134319         23753     20526         JP
02-09-2021      130156          4355      192          JP
  1. 首先,我想从数据框中找出缺失的月份
  2. 为lost 和new 填充丢失的月份数据,将lost 和new 的上个月数据值拆分到这些丢失的月份lost 和new 列中。 例如: 上述数据框中缺少 4 月和 5 月 6 月,下一个可用数据是 7 月,其中包含丢失的 18074 和新的 40108。我们需要将这些值溢出到丢失的月份(4 月、5 月、6 月),包括 july.so 丢失 18074/4 = 4518 到每个丢失的月份,包括 7 月。所以最终的输出会是这样的。

输出应该是:

Date           Emailable    Lost_Fans   New_Fans    Country

12-10-2020      121134                                 JP
06-11-2020      120859         350         75          JP
18-12-2020      101857        19128       126          JP
29-01-2021      105760         5029      8932          JP
16-02-2021      115437         1279      10956         JP
01-03-2021      115512          517       592          JP 
30-04-2021       0              4518     10027         JP
31-05-2021       0              4518     10027         JP
30-06-2021       0              4518     10027         JP
12-07-2021      137546         4518      10027         JP
11-08-2021      134319         23753     20526         JP
02-09-2021      130156          4355      192          JP

【问题讨论】:

    标签: python pandas


    【解决方案1】:
    1. 要查找缺失的月份,请使用以下代码:

      
           months = []
           miss_months = []
           for i in range(len(df.Date)):
               if df.Date[i].split('-')[1][0] != '0':
                   months.append(df.Date[i].split('-')[1])
               else:
                   months.append(df.Date[i].split('-')[1][1])
           for j in range(1,13):
               if str(j) in months:
                   pass
               else:
                   miss_months.append(j)
           print(miss_months)
       

    在从数据框中提取月份时,我注意到所有检索到的月份都是 2 个字符串。例如:'07'、'08'、'11'等。所以我写了一些代码来检查检索到的第一个字符是否为0。

    1. 要获得最终输出,请使用以下代码:

      
           def Insert_row(row_number, df, row_value):
               start_upper = 0
               end_upper = row_number
               start_lower = row_number
               end_lower = df.shape[0]
               upper_half = [*range(start_upper, end_upper, 1)]
               lower_half = [*range(start_lower, end_lower, 1)]
               lower_half = [x.__add__(1) for x in lower_half]
               index_ = upper_half + lower_half
               df.index = index_
               df.loc[row_number] = row_value
               df = df.sort_index()
               return df
           row_number = [6,7,8]
           the_date = ['30-04-2021','31-05-2021','30-06-2021']
           for k in range(len(row_number)):
               row_value = [the_date[k],0,18074//4,10027,'JP']
               df = Insert_row(row_number[k], df, row_value)
           print(df)
       

    在这里,我创建了一个函数 Insert_row() 以使添加行更容易。

    【讨论】:

      【解决方案2】:

      代码的想法是首先为缺失的月份创建 NaN 行。然后使用以下值 (bfill) 填充行。然后将结果除以 1(如果不涉及填充),或者除以连续 NaN 的数量 + 1:

      # If Date is a string, convert to datetime:
      df.Date = pd.to_datetime(df.Date, format="%d-%m-%Y")
      
      # make the month the index 
      df.set_index(df.Date.dt.to_period("M"), inplace=True)
      
      # add rows for missing months
      df = df.reindex(pd.period_range(df.index[0], df.index[-1], freq='M'))
      
      # group the consecutive NaNs
      group_nans = df.Lost_Fans.isna().groupby(df.Lost_Fans.notna().cumsum())
      
      # for each NaN group, broadcast their length & shift it one row lower
      consecutive_nans = group_nans.transform("sum").shift(fill_value=0).astype(int)
      divisor = consecutive_nans + 1
      
      # fill NaNs backwards, and divide by number of consecutive nans + 1    
      df.Lost_Fans = df.Lost_Fans.fillna(method="bfill").astype(int) // divisor
      df.New_Fans = df.New_Fans.fillna(method="bfill").astype(int) // divisor
      
      df.Emailable = df.Emailable.fillna(0).astype(int)
      df.Country = df.Country.fillna(method="bfill")
      

      生成的数据框:

                    Date  Emailable  Lost_Fans  New_Fans Country
      2020-10 2020-10-12     121134          0         0      JP
      2020-11 2020-11-06     120859        350        75      JP
      2020-12 2020-12-18     101857      19128       126      JP
      2021-01 2021-01-29     105760       5029      8932      JP
      2021-02 2021-02-16     115437       1279     10956      JP
      2021-03 2021-03-01     115512        517       592      JP
      2021-04        NaT          0       4518     10027      JP
      2021-05        NaT          0       4518     10027      JP
      2021-06        NaT          0       4518     10027      JP
      2021-07 2021-07-12     137546       4518     10027      JP
      2021-08 2021-08-11     134319      23753     20526      JP
      2021-09 2021-09-02     130156       4355       192      JP
      

      您可以替换 Date 列的缺失 (NaT) 值,例如:

      import numpy as np
      
      # replace NaTs with a timestamp from the month-index
      # it will use the first day of the month
      df.Date = np.where(df.Date.isnull(), df.index.to_timestamp(), df.Date)
      

      【讨论】:

      • 您好,感谢您的回复。我在运行这行代码时收到错误“ValueError: invalid literal for int() with base 10: '”:df.Lost_Fans = df.Lost_Fans.fillna(method="bfill").astype(int) //除数 df.New_Fans = df.New_Fans.fillna(method="bfill").astype(int) // 除数
      • 啊,Lost_Fans/New_Fans 列目前似乎是字符串数据类型,并且包含一些空值。首先将列转换为整数类型,用 0 填充缺失值。像这样:stackoverflow.com/a/42719778/463796
      • 嗨,我在这里有点困惑,我怎样才能得到输入数据帧以及结果数据帧中存在的日期。我不想在日期列中删除日期。我尝试使用 date_range 但没有用
      • 我已经编辑了答案以保留日期列,因此您仍然可以访问完整日期(或只有 df.Date.dt.day 的日期)。如果您想填写新添加的行中出现的 NaT,还有一些代码。
      猜你喜欢
      • 1970-01-01
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2018-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多