检查混合类型列的值是否等于 0(带 timedelta 和浮点数)
Check if value is equal to 0 for mixed type column (with timedelta and floats)
假设我们有以下数据框。实际情况是熔化后柱子的比较,这就是混合类型的原因。
df = pd.DataFrame({'value':[0.0, 0.0, pd.Timedelta(hours=1), pd.Timedelta(0)]})
value
0 0
1 0
2 0 days 01:00:00
3 0 days 00:00:00
我想做的是检查它是否等于 0
并基于此创建一个条件列。
所以首先我们要获取一个布尔值来标记哪些行为 0。
简单地使用 eq
或 ==
,是行不通的:
df['value'].eq(0)
0 True
1 True
2 False
3 False
Name: value, dtype: bool
这是因为我们可能有一个 Timedelta
类型,所以我想让我们将 timedelta 转换为秒。所以我检查了:
df['value'].apply(type) == pd._libs.tslibs.timedeltas.Timedelta
0 False
1 False
2 True
3 True
Name: value, dtype: bool
哪个有效。
然后用了,没用:
np.where(df['value'].apply(type) == pd._libs.tslibs.timedeltas.Timedelta,
df['value'].total_seconds(),
df['value'])
'Series' object has no attribute 'total_seconds'
最后,这有效。
df['value'].apply(lambda x: x.total_seconds() if type(x) == pd._libs.tslibs.timedeltas.Timedelta else x).eq(0)
0 True
1 True
2 False
3 True
Name: value, dtype: bool
但是比较慢,看起来不像"panda like".
所以我的问题是,是否有更快更优化的解决方案?
您可以使用:
df.eq(pd.Timedelta(0))|df.eq(0)
value
0 True
1 True
2 False
3 True
我会 'upgrade' int
到 timedelta
pd.to_timedelta(df.value).dt.total_seconds()==0
Out[232]:
0 True
1 True
2 False
3 True
Name: value, dtype: bool
假设我们有以下数据框。实际情况是熔化后柱子的比较,这就是混合类型的原因。
df = pd.DataFrame({'value':[0.0, 0.0, pd.Timedelta(hours=1), pd.Timedelta(0)]})
value
0 0
1 0
2 0 days 01:00:00
3 0 days 00:00:00
我想做的是检查它是否等于 0
并基于此创建一个条件列。
所以首先我们要获取一个布尔值来标记哪些行为 0。
简单地使用 eq
或 ==
,是行不通的:
df['value'].eq(0)
0 True
1 True
2 False
3 False
Name: value, dtype: bool
这是因为我们可能有一个 Timedelta
类型,所以我想让我们将 timedelta 转换为秒。所以我检查了:
df['value'].apply(type) == pd._libs.tslibs.timedeltas.Timedelta
0 False
1 False
2 True
3 True
Name: value, dtype: bool
哪个有效。
然后用了,没用:
np.where(df['value'].apply(type) == pd._libs.tslibs.timedeltas.Timedelta,
df['value'].total_seconds(),
df['value'])
'Series' object has no attribute 'total_seconds'
最后,这有效。
df['value'].apply(lambda x: x.total_seconds() if type(x) == pd._libs.tslibs.timedeltas.Timedelta else x).eq(0)
0 True
1 True
2 False
3 True
Name: value, dtype: bool
但是比较慢,看起来不像"panda like".
所以我的问题是,是否有更快更优化的解决方案?
您可以使用:
df.eq(pd.Timedelta(0))|df.eq(0)
value
0 True
1 True
2 False
3 True
我会 'upgrade' int
到 timedelta
pd.to_timedelta(df.value).dt.total_seconds()==0
Out[232]:
0 True
1 True
2 False
3 True
Name: value, dtype: bool