【问题标题】:Use filename as an indicator to process datetime columns using pandas使用文件名作为指标来处理使用 pandas 的日期时间列
【发布时间】:2021-07-10 06:20:21
【问题描述】:

我正在将 15 个 csv 文件读入 pandas 数据框。我想要在最终数据框中的列分布在多个 csv 文件中

文件 1 到文件 8 的文件名模式 - Med*(例如:Med1、Med2、Medtest、Medkill)

文件 1 到文件 8 的样本数据如下所示

df = pd.DataFrame({'person_id': [101,101,101,101,202,202,202],
                   'start_date':['5/7/2013 09:27:00 AM','09/08/2013 11:21:00 AM','06/06/2014 08:00:00 AM','06/06/2014 05:00:00 AM','12/11/2011 10:00:00 AM','13/10/2012 12:00:00 AM','13/12/2012 11:45:00 AM'],'type':['O','I','O','O','I','O','I']})

文件 9 到文件 12 的文件名模式 - Adm*(例如:Adm1、Adm2、Admaasd、Admmed)

文件 9 到文件 12 的样本数据如下所示

df = pd.DataFrame({'person_id': [101,101,101,101,202,202,202],
                        'start_date':['5/7/2013 09:27:00 AM','09/08/2013 11:21:00 AM','06/06/2014 08:00:00 AM','06/06/2014 05:00:00 AM','12/11/2011 10:00:00 AM','13/10/2012 12:00:00 AM','13/12/2012 11:45:00 AM'],
                        'end_date':['5/12/2013 09:27:00 AM',np.nan,'06/11/2014 08:00:00 AM',np.nan,'12/16/2011 10:00:00','10/18/2012 00:00:00',np.nan],
                        'type':['O','I','O','O','I','O','I']})

文件 13 到文件 15 的文件名模式 - cas*(例如:castest、caste22、caskill)

文件 13 到文件 15 的样本数据如下所示

df = pd.DataFrame({'person_id': [101,101,101],
                   'start_date':['5/2/2013 09:27:00 AM','09/03/2013 11:21:00 AM','06/01/2014 08:00:00 AM'],'dur':['3w','3m','2d']})

在我的最终数据框中,我希望列名如下所示

person_ID, start_date, end_date

正如您在file 1 to 8 中看到的那样,没有end_date 列。因为end_date = start_date。所以我们必须将start_date 的值复制到end_date

同样在file 13 to 15 中,我们也没有end_date 列。但是我们可以通过将duration 列值添加到start_date 来导出end_date

我尝试了以下

pat_dir = ['Med*.csv','C:\\test\\Adm*.csv', 'C:\\test12\\test13\\cas*.csv']
files_grabbed = [] 
cols = ['person_id','start_date','end_date']
dfs = [pd.read_csv(f, sep=",",low_memory=False).reindex(columns=cols) 
       for f in files_grabbed]

尽管上面的代码使用NA 在最终数据框中创建了end_date 列(对于原始文件中没有此列的文件)。

问题是如何识别带有模式的文件需要不同的 end_dates 处理方式

Med* - 将 start_date 值复制为 end_date

cas* - 将持续时间添加到 start_date 并将它们存储在 end_date 列中

通过我的代码,我创建了一个最终的数据框,但不知道如何将 end_date 逻辑应用于这些文件?

是否可以在创建最终数据帧之前或在读取操作期间添加这些逻辑?

【问题讨论】:

  • add duration to start_date - 有持续时间栏吗?
  • 是的,在示例数据框中...dur
  • 答案已编辑,您可以测试一下吗?

标签: python pandas dataframe numpy series


【解决方案1】:

使用if statemenet 进行文件名测试:

import os

#custom function for add values by duration
def func(x):

    if pd.isna(x['dur']):
        return x['start_date']

    elif x[1] == 'w':
        return x['start_date'] + pd.offsets.DateOffset(weeks=x[0])
    elif x[1] == 'm':
        return x['start_date'] + pd.offsets.DateOffset(months=x[0])
    elif x[1] == 'd':
        return x['start_date'] + pd.offsets.DateOffset(days=x[0])
    else:
        return x['start_date']

dfs = []
for f in files_grabbed:
    df = pd.read_csv(f, sep=",",low_memory=False)
    name = os.path.basename(f)
    if name.startswith('Med'):
        dfs.append(df.assign(end_date = df['start_date']))

    elif name.startswith('cas'):

        df['start_date'] = pd.to_datetime(df['start_date'])
        df[[0,1]] = df['dur'].str.extract('(\d+)(\D+)')
        df[0] = df[0].fillna(0).astype(int)
     
        df['end_date'] = df.apply(func, axis=1)
        dfs.append(df)
    else:
        dfs.append(df)

【讨论】:

  • @TheGreat - 如果 Na 在 Dur column 中会发生什么?
  • @TheGreat - 超级,很高兴能帮上忙。 cas 的测试方式,如果有类似m,d,w 之类的需要修改函数。
  • 您好一个小问题,我将代码更新为如下所示
  • def f(x): if x[1].lower().startswith('w'): return x['start_date'] + pd.offsets.DateOffset(weeks=x[0]) if x[1].lower().startswith('m'): return x['start_date'] + pd.offsets.DateOffset(months=x[0]) if x[1].lower().startswith('d'): return x['start_date'] + pd.offsets.DateOffset(days=x[0]) if x[1].lower().startswith('y'): return x['start_date'] + pd.offsets.DateOffset(years=x[0])
  • 当我最终做到这一点df.update(df[[0,1]]).fillna(0).astype(int),我得到一个错误,上面写着AttributeError: 'NoneType' object has no attribute 'fillna'
猜你喜欢
  • 2015-09-14
  • 2019-03-20
  • 2012-10-16
  • 2013-07-27
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
相关资源
最近更新 更多