pandas ISIN函数不适用于日期

whhtz7ly  于 2023-02-02  发布在  其他
关注(0)|答案(5)|浏览(241)
d = {'Dates':[pd.Timestamp('2013-01-02'),
              pd.Timestamp('2013-01-03'),
              pd.Timestamp('2013-01-04')],
     'Num1':[1,2,3],
     'Num2':[-1,-2,-3]}

df = DataFrame(data=d)

我们有这个 Dataframe

Dates                  Num1 Num2
0   2013-01-02 00:00:00  1  -1
1   2013-01-03 00:00:00  2  -2
2   2013-01-04 00:00:00  3  -3  

Dates    datetime64[ns]
Num1              int64
Num2              int64
dtype: object

这给了我

df['Dates'].isin([pd.Timestamp('2013-01-04')])  

0    False
1    False
2    False
Name: Dates, dtype: bool

我期待一个真的日期“2013-01-04”,我错过了什么?我使用的是最新的0. 12版本的Pandas

7gs2gvoe

7gs2gvoe1#

这对我很有效。

df['Dates'].isin(np.array([pd.Timestamp('2013-01-04')]).astype('datetime64[ns]'))

我知道这有点冗长。但是以防万一你需要让它工作,这会有帮助。参考https://github.com/pydata/pandas/issues/5021了解更多细节。

lbsnaicq

lbsnaicq2#

我也有相同版本的Pandas,@DSM的回答很有帮助。另一个变通方法是使用apply方法:

>>> df.Dates.apply(lambda date: date in [pd.Timestamp('2013-01-04')])

0    False
1    False
2     True
Name: Dates, dtype: bool
alen0pnh

alen0pnh3#

是的,我觉得这是个bug,它可以归结为lib.ismember的以下部分:

for i in range(n):
    val = util.get_value_at(arr, i)
    if val in values:
        result[i] = 1
    else: 
        result[i] = 0

valnumpy.datetime64对象,而valuesTimestamp对象的set。测试成员资格应该有效,但没有:

>>> import pandas as pd, numpy as np
>>> ts = pd.Timestamp('2013-01-04')
>>> ts
Timestamp('2013-01-04 00:00:00', tz=None)
>>> dt64 = np.datetime64(ts)
>>> dt64
numpy.datetime64('2013-01-03T19:00:00.000000-0500')
>>> dt64 == ts
True
>>> dt64 in [ts]
True
>>> dt64 in {ts}
False

我通常认为这种行为--在列表中工作,而不是在集合中工作--是由于__hash__出现了问题:

>>> hash(dt64)
1357257600000000
>>> hash(ts)
-7276108168457487299

如果哈希值不相同,就不能在集合中进行成员资格测试。我可以想出一些方法来解决这个问题,但选择最好的方法将取决于他们在实现时间戳时所做的设计选择,我没有资格对此发表评论。

vatpfxk5

vatpfxk54#

我发现在我的例子中使用字符串效果更好:

df['Dates'].isin(['2013-01-04'])
0    False
1    False
2     True
Name: Dates, dtype: bool
df_qry = df['Dates'][df['Num1']>=2]
1   2013-01-03
2   2013-01-04
Name: Dates, dtype: datetime64[ns]
df_mask = df['Dates'].isin(df_qry.astype(str))
0    False
1     True
2     True
Name: Dates, dtype: bool
df[df_mask]
    Dates   Num1    Num2
1   2013-01-03  2   -2
2   2013-01-04  3   -3

只是一个侧记:这是超级方便的设置rangebreaks的plotly时间序列,如:

fig.update_yaxes(rangebreaks=[dict(values=df.index[df_mask].astype(str))])
nhaq1z21

nhaq1z215#

由于某种原因,你是否有“时间”与你的日期,该序列不正确.尝试:

df['Dates'] = df['Dates'].dt.normalize()
df['Dates'].isin([pd.Timestamp('2013-01-04')])

你会从你的“日期时间”中丢失“时间”,但如果你的时间不重要,它实际上是有效的:)。

相关问题