首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在支持多种数据格式的Pandas中合并日期?

如何在支持多种数据格式的Pandas中合并日期?
EN

Stack Overflow用户
提问于 2019-10-08 04:44:32
回答 1查看 127关注 0票数 3

我正在编写一个Pandas例程的库,它需要能够处理可能是不同类型的数据帧中的日期。具体来说,我得到了相当多的datetime.datepandas._libs.tslib.Timestamp类型的不同组合。据报道(并通过我的测试证实)这与具有多索引设置然后重置的帧有关。(请参阅我前面的问题What changes type of date in this pandas code?,它解决了在多索引之间来回切换时类型被更改的问题。)

这里有一个简短的(但人为的)例子:

代码语言:javascript
复制
import pandas as pd
df = pd.DataFrame(
   data={
      'date' : ['2019-01-01', '2019-01-02', '2019-01-03'], 
      'value' : [1, 2, 3], 
      'other' : [11, 12, 13]
   }
)

df.date = pd.to_datetime(df.date).dt.date

print df.head()
         date  other  value
0  2019-01-01     11      1
1  2019-01-02     12      2
2  2019-01-03     13      3

df_reindex = df.set_index(['date','other']).reset_index()
         date  other  value
0  2019-01-01     11      1
1  2019-01-02     12      2
2  2019-01-03     13      3

print pd.merge(df, df_reindex, on='date')
Empty DataFrame
Columns: [date, other_x, value_x, other_y, value_y]
Index: []

print pd.merge(df, df, on='date')
         date  other_x  value_x  other_y  value_y
0  2019-01-01       11        1       11        1
1  2019-01-02       12        2       12        2
2  2019-01-03       13        3       13        3

print pd.merge(df_reindex, df_reindex, on='date')
        date  other_x  value_x  other_y  value_y
0 2019-01-01       11        1       11        1
1 2019-01-02       12        2       12        2
2 2019-01-03       13        3       13        3

print type(df.date[0])
<type 'datetime.date'>

print type(df_reindex.date[0])
<class 'pandas._libs.tslib.Timestamp'>

在这里,dfdf_reindex具有本质上相同的数据内容,但是,由于类型在set_index处已在Pandas内部更改,因此它们之间的合并是空的,而两者之间的“自合并”给出了预期的结果(尽管在这里,人为设计的情况下,是多余的和微不足道的)。

当然,实际情况下,不需要像这样随意地设置和重置索引就可以达到这一点-实际数据通过多位代码,在不同阶段执行不同的索引要求,并且合并是在具有一些不重叠列的帧之间进行的。

我的另一个问题是使用NumPy datetimes,但这似乎是徒劳的,因为转换显然会导致两种有问题的数据类型之一,即底层的Pandas类:

代码语言:javascript
复制
df_numpy = df.copy()

df_numpy.date = df.date.apply(np.datetime64)

print type(df.date[0])
<type 'datetime.date'>

print type(df_numpy.date[0])
<class 'pandas._libs.tslib.Timestamp'>

(更不用说我是在一个现有的框架中工作,所以在这一点上可能不可能强制所有框架都具有NumPy类型而不是Pandas类型。)

我需要做的是能够合并库代码中的表,无论它们是否被我控制之外的调用者如此操作。我获得的作为输入的数据帧不能更改。我可以复制它们并在副本上实现直接转换(就像这里的pandas merge on date column issue),但是帧有时很大,除非没有其他选择,否则我不想复制它们。

有没有办法让合并程序将它们识别为等价的?如果没有,有没有避免这里暴露的转换问题的日期格式的最佳实践选择?

EN

回答 1

Stack Overflow用户

发布于 2019-10-08 23:12:42

有没有办法让merge将它们识别为等价的?

不,不能使用当前的pandas code

代码语言:javascript
复制
    # datetimelikes must match exactly
    elif is_datetimelike(lk) and not is_datetimelike(rk):
        raise ValueError(msg)
    elif not is_datetimelike(lk) and is_datetimelike(rk):
        raise ValueError(msg)
    elif is_datetime64tz_dtype(lk) and not is_datetime64tz_dtype(rk):
        raise ValueError(msg)
    elif not is_datetime64tz_dtype(lk) and is_datetime64tz_dtype(rk):
        raise ValueError(msg)

如果没有,有没有避免这里暴露的转换问题的日期格式的最佳实践选择?

我从你的问题中了解到,数据帧和它们的数据类型不在你的控制范围之内,而且它们不能改变,所以这个问题不会给我们带来任何帮助。

您需要的是像SQL中那样的条件连接。有一个旧的开放issue用于这个功能,自2014年以来没有任何活动。(邀请PRs...)

一种可能的解决方法可能是这样的:

代码语言:javascript
复制
def merge_on_date(left, right, on):
    from pandas.core.dtypes.common import is_datetimelike
    try:
        return pd.merge(left, right, on=on)
    except:
        if is_datetimelike(right[on]):
            return pd.merge(left, right.assign(**{on: eval('right[on].dt.date')}), on=on)
        else:
            return pd.merge(left.assign(**{on: eval('left[on].dt.date')}), right, on=on)

结果:

代码语言:javascript
复制
>>> merge_on_date(df, df_reindex, 'date')
         date  value_x  other_x  other_y  value_y
0  2019-01-01        1       11       11        1
1  2019-01-02        2       12       12        2
2  2019-01-03        3       13       13        3
>>> merge_on_date(df_reindex, df, 'date')
         date  other_x  value_x  value_y  other_y
0  2019-01-01       11        1        1       11
1  2019-01-02       12        2        2       12
2  2019-01-03       13        3        3       13

然而,这一大缺点是引擎盖下的assign makes a copy

PS:我刚刚在你的例子中看到了pd.merge(df, df_reindex, on='date')会产生一个空的数据帧。从版本0.22.0开始,这应该会引发ValueError。您使用的是什么版本?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58276892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档