【问题标题】:How to get missing date in columns using python pandas [closed]如何使用python pandas获取列中缺失的日期[关闭]
【发布时间】:2021-06-29 15:25:26
【问题描述】:

我有以下数据框,我想在其中获取丢失的日期及其在 pandas 中的键。

     size     number     key      date
0  153.2 K    12345     Hello     20181001
1  153.2 K    12345     No        20181001
2  153.2 K    12345     Hello     20181003
3  153.2 K    12345     No        20181003
4  153.2 K    12345     Hello     20181004
5  153.2 K    12345     No        20181004

我希望输出为,

  key      date
  Hello     20181002
  No        20181002

提前致谢

【问题讨论】:

  • 如果缺少日期,你怎么知道钥匙、数量和大小?此外,您还没有在代码中指定您面临的问题。
  • 这就是问题所在,如果我有 2 个键,那么代码应该检查两个 @It_is_Chris 是否缺少日期
  • 好吧,但这没有任何意义。您如何知道未进行观察的日期的其他值?
  • 对不起,我的错,编辑了这个问题。所以我只想要密钥和日期@It_is_Chris

标签: python pandas date


【解决方案1】:

你可以通过一些花哨的重塑来做到这一点:

(df.pivot('date', 'key')
   .reindex(np.arange(df['date'].min(), df['date'].max()+1))
   .stack('key', dropna=False)
   .loc[lambda x: x['size'].isna()]
   .index
   .to_frame(index=False))

输出:

       date    key
0  20181002  Hello
1  20181002     No

如何?

  • 重塑数据框,使每行有一个日期

  • 接下来,重新索引数据框以填充缺失的日期

  • 重塑数据框堆叠键,但保留 NaN 值

  • 使用isna过滤数据框以仅缺失值

  • 使用 to_frame 将索引转换为数据帧

下面@Cimbali 提到的更新地址日期问题

df['date'] = pd.to_datetime(df['date'], format='%Y%m%d')
(df.pivot('date', 'key')
   .reindex(pd.date_range(df['date'].min(), df['date'].max(), freq='D'))
   .stack('key', dropna=False)
   .loc[lambda x: x['size'].isna()]
   .index
   .to_frame(index=False))

输出:

           0    key
0 2018-10-02  Hello
1 2018-10-02     No

【讨论】:

  • 这仅适用于日期都在同一个月内。只要您的np.arange 超过 1,就会给您很多最后 2 位 > 31 的非日期。
  • @好点,我们可以做一些类似的转换日期到日期时间然后使用pd.date_range
  • 文件 "/home/gaurav/.local/lib/python3.9/site-packages/pandas/core/tools/datetimes.py",第 456 行,在 _convert_listlike_datetimes 值中,tz = 转换。 datetime_to_datetime64(arg) 文件“pandas/_libs/tslibs/conversion.pyx”,第 350 行,在 pandas._libs.tslibs.conversion.datetime_to_datetime64 类型错误:无法识别的值类型: 在处理上述异常期间,另一个发生异常:@ScottBoston
  • Hrm... 这看起来像是 df['date'] 中的错误数据 也许您的值与 %Y%m%d 的结构不同。您可以 coerce 并将 NaN 用于不可覆盖的字符串,如下所示:df['date'] = pd.to_datetime(df['date'], format='%Y%m%d', errors='coerce')
  • @ScottBoston 我们可以分别计算每个键的日期吗?像 Hello 的日期范围从 20190101 到 20190120 而 No 的日期范围从 2019015 到 20190119
【解决方案2】:

如果我们将日期沿一维对齐,则更容易查看常用值(在索引上)和填充位置(在列上)。我们可以通过pivot_table 做到这一点。 (这里的 value 只是一个占位符,包含所有 1s。)

>>> tab = df.assign(value=1).pivot_table(index='key', columns='date', values='value')
>>> tab
date   20181001  20181003  20181004
key                                
Hello         1         1         1
No            1         1         1

melt 允许我们进行相反的转换:

>>> tab.reset_index().melt(id_vars='key').drop(columns='value')
     key      date
0  Hello  20181001
1     No  20181001
2  Hello  20181003
3     No  20181003
4  Hello  20181004
5     No  20181004

所以如果我们想要一个中间步骤来添加缺失的日期,我们应该先将它们转换为日期并使用pd.date_range

>>> avail_dates = pd.to_datetime(tab.columns, format='%Y%m%d')
>>> avail_dates
DatetimeIndex(['2018-10-01', '2018-10-03', '2018-10-04'], dtype='datetime64[ns]', name='date', freq=None)
>>> all_dates = pd.date_range(avail_dates.min(), avail_dates.max(), freq='D')
>>> tab_filled = tab.reindex(all_dates.strftime('%Y%m%d').astype(int), axis='columns')
>>> tab_filled
       20181001  20181002  20181003  20181004
key                                          
Hello         1       NaN         1         1
No            1       NaN         1         1

最后只得到新的列,然后做我们melt的把戏:

>>> missing = tab_filled.drop(columns=tab.columns).reset_index().melt('key').drop(columns=['value'])
>>> missing
     key  variable
0  Hello  20181002
1     No  20181002

这是一个基于相同原理的较短变体,我们首先构建日期,然后是我们可以melt 的合成数据框:

>>> dates = pd.date_range(
...     *pd.to_datetime(df['date'], format='%Y%m%d').agg(['min', 'max']), freq='D'
... ).strftime('%Y%m%d').astype(int)
>>> dates
Int64Index([20181001, 20181002, 20181003, 20181004], dtype='int64')
>>> pd.DataFrame(index=pd.Index(df['key'].unique(), name='key'),
...              columns=dates.difference(df['date']))\
... .reset_index().melt('key').drop(columns=['value'])
     key  variable
0  Hello  20181002
1     No  20181002

【讨论】:

  • >>> tab = df.assign(value=np.nan).pivot_table(index='key', columns='date', values='value') 这给了我空数据框@辛巴里
  • @Gaurav 我的意思是df.assign(value=1),如解释中所述。修好了。
  • 我们可以分别计算每个键的日期吗?像 Hello 的日期范围从 20190101 到 20190120 而 No 的日期范围从 2019015 到 20190119
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2020-06-03
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
相关资源
最近更新 更多