python - 如何将pandas数据框的单行拆分为两行?

标签 python pandas dataframe

我试图将数据框的单行分成两行。在数据框中,开始和结束列可用。我想根据条件拆分行。

我有一个如下所示的数据框:

symbol,start,end,size
ABC,2015-08-27 18:00:00,2015-08-28 05:00:00,12
ABC,2015-11-20 02:00:00,2015-11-20 06:00:00,5
ABC,2016-01-22 03:00:00,2016-01-22 06:00:00,4
PQR,2016-02-12 02:00:00,2016-02-12 06:00:00,5
PQR,2016-02-12 22:00:00,2016-02-13 03:00:00,6
PQR,2016-02-12 02:00:00,2016-02-12 07:00:00,6

条件:

  1. 如果开始和结束是同一天,则无需执行任何操作。
  2. 如果开始和结束日期不同,则需要将其分成两行。

示例:让我们考虑如下行:

PQR,2016-02-12 22:00:00,2016-02-13 03:00:00,6

在上面的行中,start 包含第 12 日,end 包含第 13 日,因此需要将其分成两行,如下所示:

PQR,2016-02-12 22:00:00,2016-02-12 23:00:00,2
PQR,2016-02-12 00:00:00,2016-02-13 03:00:00,4

如果该行包含三天(如第 12 日开始和第 14 日结束),则需要将其拆分为三行。

预期输出为:

symbol,start,end,size
ABC,2015-08-27 18:00:00,2015-08-27 23:00:00,6
ABC,2015-08-28 00:00:00,2015-08-28 05:00:00,6
ABC,2015-11-20 02:00:00,2015-11-20 06:00:00,5
ABC,2016-01-22 03:00:00,2016-01-22 06:00:00,4
PQR,2016-02-12 02:00:00,2016-02-12 06:00:00,5
PQR,2016-02-12 22:00:00,2016-02-12 23:00:00,2
PQR,2016-02-12 00:00:00,2016-02-13 03:00:00,4
PQR,2016-02-12 02:00:00,2016-02-12 07:00:00,6

最佳答案

选项 1

迭代行并构建一个新的 DataFrame 逐行附加。

import pandas as pd
import datetime

df2 = pd.DataFrame(columns=df.columns)

for (_,r) in df.iterrows():

    while r['start'].date()<r['end'].date():
        # create new row
        newR = r.copy()
        newR['end']=newR['start']
        newR['end']=newR['end'].replace(hour=23)

        newSize = 24-newR['start'].hour
        newR['size']=newSize

        # update row to process 
        r['start']=r['start']+datetime.timedelta(days=1)
        r['start']=r['start'].replace(hour=0)

        r['size'] = r['size'] - newSize

        df2 = df2.append(newR)

    df2 = df2.append(r)

df2.reset_index(drop=True, inplace=True)

选项 2

使用掩码和递归调用来执行Dataframe操作,以防原始Dataframe中的行在超过两天内被分割。

import pandas as pd
import numpy as np
import datetime


def splitMultiDayRows(df):
    mask = df['end'].dt.day>df['start'].dt.day

    if np.any(mask):
        df_new = df.loc[mask]

        newSizes = 24-df.loc[mask,'start'].dt.hour

        df.loc[mask,'end'] = df.loc[mask,'start']
        df.loc[mask,'end'] = df.loc[mask,
                                    'end'].apply(lambda x:
                                                 x.replace(hour=23))
        df.loc[mask,'size'] = newSizes

        df_new.loc[:,'start'] = df_new['start']+datetime.timedelta(days=1)
        df_new.loc[:,'start'] = df_new['start'].apply(lambda x:
                                                      x.replace(hour=0))

        df_new.loc[:,'size'] = df_new['size'] - newSizes

        return pd.concat([df,splitMultiDayRows(df_new)])
    else:
        return df

与通话一起使用:

splitMultiDayRows(df.copy()).\
sort_values(['symbol','start']).\
reset_index(drop=True)

关于python - 如何将pandas数据框的单行拆分为两行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50962722/

相关文章:

python - 数组更改条目,尽管没有代码这样做......它是什么?

python - 寻找骰子概率

Python pandas整数YYYYMMDD到日期时间

python - 如何在 Python Pivot_table 中使用 agg_func = 'All'

python - 将一列中的数组值转换为原始 DataFrame 的列的最佳方法是什么?

Python - 使用 WConio 将 unicode 打印到控制台窗口

python - 为什么全局变量 fsize 会被清除?

python - 向 Pandas Dataframe 中的字符串添加前导零

python - 解析 CSV header

scala - 使用 Scala 将 DataFrame 单行转置为 Spark 中的列