我试图取包含日期的两列的最大行数(和最小值)。
from datetime import date
import pandas as pd
import numpy as np
df = pd.DataFrame({'date_a' : [date(2015, 1, 1), date(2012, 6, 1),
date(2013, 1, 1), date(2016, 6, 1)],
'date_b' : [date(2012, 7, 1), date(2013, 1, 1),
date(2014, 3, 1), date(2013, 4, 1)]})
df[['date_a', 'date_b']].max(axis=1)
Out[46]:
0 2015-01-01
1 2013-01-01
2 2014-03-01
3 2016-06-01如预期的那样。但是,如果数据文件包含单个NaN值,则整个操作将失败。
df_nan = pd.DataFrame({'date_a' : [date(2015, 1, 1), date(2012, 6, 1),
np.NaN, date(2016, 6, 1)],
'date_b' : [date(2012, 7, 1), date(2013, 1, 1),
date(2014, 3, 1), date(2013, 4, 1)]})
df_nan[['date_a', 'date_b']].max(axis=1)
Out[49]:
0 NaN
1 NaN
2 NaN
3 NaN
dtype: float64这里发生什么事情?我正期待着这个结果
0 2015-01-01
1 2013-01-01
2 NaN
3 2016-06-01如何才能做到这一点?
发布于 2017-08-26 20:35:08
我认为最好的解决方案是使用适当的dtype。熊猫提供了一个非常完整的datetime dtype。所以请注意,您使用的是object类型..。
>>> df
date_a date_b
0 2015-01-01 2012-07-01
1 2012-06-01 2013-01-01
2 NaN 2014-03-01
3 2016-06-01 2013-04-01
>>> df.dtypes
date_a object
date_b object
dtype: object但是请注意,当您使用
>>> df2 = df.apply(pd.to_datetime)
>>> df2
date_a date_b
0 2015-01-01 2012-07-01
1 2012-06-01 2013-01-01
2 NaT 2014-03-01
3 2016-06-01 2013-04-01
>>> df2.min(axis=1)
0 2012-07-01
1 2012-06-01
2 2014-03-01
3 2013-04-01
dtype: datetime64[ns]发布于 2017-08-26 20:25:22
当date对象与列中的浮点数(如NaN)混合时,似乎会发生这种情况。默认情况下,numeric_only标志是由于单个浮动值而设置的。例如,将您的df_nan替换为:
df_float = pd.DataFrame({'date_a' : [date(2015, 1, 1), date(2012, 6, 1),
1.023, date(2016, 6, 1)],
'date_b' : [date(2012, 7, 1), 3.14,
date(2014, 3, 1), date(2013, 4, 1)]})
print(df_float.max(1))
0 NaN
1 NaN
2 NaN
3 NaN
dtype: float64如果该标志被手动设置为false,这将正确地抛出一个TypeError,因为:
print(date(2015, 1, 1) < 1.0)
TypeError Traceback (most recent call last)
<ipython-input-362-ccbf44ddb40a> in <module>()
1
----> 2 print(date(2015, 1, 1) < 1.0)
TypeError: unorderable types: datetime.date() < float()然而,熊猫似乎把一切都胁迫给了NaN。作为一种解决办法,使用str转换为df.astype似乎可以做到这一点:
out = df_nan.astype(str).max(1)
print(out)
0 2015-01-01
1 2013-01-01
2 nan
3 2016-06-01
dtype: object在这种情况下,按字典顺序排序会产生与以前相同的解决方案。
否则,作为juan suggests,您可以使用pd.to_datetime转换为datetime
out = df_nan.apply(pd.to_datetime, errors='coerce').max(1)
print(out)
0 2015-01-01
1 2013-01-01
2 2014-03-01
3 2016-06-01
dtype: datetime64[ns]发布于 2017-08-26 21:19:40
下列措施应能发挥作用:
>>> df_nan.where(df_nan.T.notnull().all()).max(axis=1)
Out[1]:
0 2015-01-01
1 2013-01-01
2 None
3 2016-06-01
dtype: object其中:
df_nan.T.notnull().all()计算不包含np.nan的行掩码。df_nan.where()将前一个掩码应用于数据帧.max(axis=1)获得逐行最大值。这是因为所有值都是np.nan的数组的最大值是None。它允许通过不显示最大值来跟踪值丢失的行。
但是这个决定取决于您,否则@juanpa.arrivillaga将NaN转换为NaT的解决方案就是您想要的。
https://stackoverflow.com/questions/45899340
复制相似问题