Pandas:如何删除包含无效月/日列组合的行,例如2月30日?

问题描述 投票:1回答:2

我有源数据,使用31列作为日期值,每个月有一行。我已将31天的列熔化为单日列,现在我想将年,月和日列合并到日期时间(?)列中,以便按年/月/日对行进行排序。

融化后,我的数据框看起来像这样:

       year  month day   prcp
0      1893      1  01    0.0
1      1893      2  01    0.0
2      1893      3  01    0.0
3      1893      4  01    NaN
4      1893      5  01    NaN
5      1893      6  01    NaN
6      1893      7  01    NaN
7      1893      8  01    0.0
8      1893      9  01   10.0
9      1893     10  01    0.0
10     1893     11  01    0.0
11     1893     12  01    NaN
12     1894      1  01    NaN
13     1894      2  01    0.0
14     1894      3  01    NaN
...

接下来我正在尝试创建一个我可以排序的“时间”列,使用年,月和日列作为日期时间构造函数的参数。我尝试过使用这种方法:

def make_datetime(y, m, d):
    return(datetime(year=y, month=m, day=d))

df['time'] = np.vectorize(make_datetime)(df['year'].astype(int), df['month'].astype(int), df['day'].astype(int))

以上不会让我在那里,因为它在月/日列没有合理的情况下失败,例如2月29日非闰年,4月31日等等。我想我想做什么接下来是以某种方式将datetime()调用包装在try / catch中,并且当由于不兼容的月/日组合而导致其崩溃时,我应该将该行放在catch块中。如果不对所有行执行for循环,我将如何去做?还是有更好的方法来破解这个坚果?

提前感谢任何建议或见解。

python pandas
2个回答
3
投票

你可以将你的df表示传递给to_datetime

pd.to_datetime(df,errors='coerce')
Out[905]: 
#          NaT
#          NaT
#   1892-02-29
#          NaT
#          NaT
#          NaT
#   1896-02-29
#          NaT
#          NaT
dtype: datetime64[ns]
df['New']=pd.to_datetime(df,errors='coerce')
df.dropna()
Out[907]: 
   year  month  day        New
#  1892      2   29 1892-02-29
#  1896      2   29 1896-02-29

3
投票

这是使用你在try / except条款中包装的建议的一种方法。

from datetime import datetime

def dater(x):
    try:
        return datetime(year=x['year'], month=x['month'], day=x['day'])
    except ValueError:
        return None

df['date'] = df.apply(dater, axis=1)

#    year  month  day       date
# 0  1890      2   29        NaT
# 1  1891      2   29        NaT
# 2  1892      2   29 1892-02-29
# 3  1893      2   29        NaT
# 4  1894      2   29        NaT
# 5  1895      2   29        NaT
# 6  1896      2   29 1896-02-29
# 7  1897      2   29        NaT
# 8  1898      2   29        NaT

df = df.dropna(subset=['date'])

#    year  month  day       date
# 2  1892      2   29 1892-02-29
# 6  1896      2   29 1896-02-29
© www.soinside.com 2019 - 2024. All rights reserved.