Вернуть позиции ячеек даты для ValueError: ('Неизвестный формат строки:', '2020-4-') - PullRequest
1 голос
/ 28 мая 2020

Учитывая фрейм данных с несколькими беспорядочными столбцами даты, как показано ниже:

  id       date1       date2       date3
0   1   2020-5-10   2020-5-18   2021-5-17
1   2   2020.4.20   2020/5/20   2023/5/19
2   4   2020年5月7日   2020年5月20   2023年5月19
3   5  2020年4月23日    2020/5/1   2022/4/30
4   6  2020年4月12日  2020年4月20日   2022/4/19
5   7   2020年5月8日   2020年5月8日   2022年5月8日
6   8   2020年5月3号   2020年5月8号   2022年5月3号
7  12  2020—05—10  2020—05—11  2021—05—10
8  13  2020—05—08  2020—05—15  2022—05—14
9  14  2020年3月15日  2020年3月15日  2023年3月14日

Я написал функцию date_manipulate для преобразования их в стандартные даты, это формат %Y-%m-%d.

def date_manipulate(x):
    x = x.str.strip()
    x = x.str.replace(' ', '')
    x = x.str.replace('年', '-')
    x = x.str.replace('月', '-')
    x = x.str.replace('日', '')
    x = x.str.replace('号', '')
    x = x.str.replace('.', '-')
    x = x.str.replace('—', '-')
    x = pd.to_datetime(x).dt.date.astype(str)
    return x

date_cols = ['date1', 'date2', 'date3']
df[date_cols].apply(date_manipulate)

Но это вызывает ошибку значения, однако я не знаю, какая ячейка даты из оригинального Excel вызывает эту ошибку:

ValueError: ('Unknown string format:', '2020-4-')

Как мне изменить код, чтобы вернуть позиции ячеек даты чтобы помочь мне проверить? Спасибо.

Вывод из кода @ jezrael:

                date1            date2              date3
1              2020.4.20  2020-05-20 00:00:00  2023-05-19 00:00:00
4             2020年4月23日  2020-05-01 00:00:00  2022-04-30 00:00:00
5             2020年4月12日           2020年4月20日  2022-04-19 00:00:00
16             2020年5月6日  2020-05-07 00:00:00            2022年5月8日
46   2020-03-20 00:00:00  2020-04-01 00:00:00  2022-03-31 00:00:00
48   2020-03-15 00:00:00  2020-03-20 00:00:00  2021-03-19 00:00:00
53   2020-04-01 00:00:00  2020-05-01 00:00:00  2025-04-30 00:00:00
54   2020-04-03 00:00:00  2020-04-03 00:00:00  2022-04-02 00:00:00
57   2020-04-14 00:00:00  2020-04-20 00:00:00  2021-04-19 00:00:00
58             2020年4月3日  2020-04-18 00:00:00           2022年4月17日
60   2020-04-30 00:00:00           2020年5月10号  2022-05-09 00:00:00
62             2020年5月7日  2020-05-06 00:00:00  2021-05-05 00:00:00
93             2020年5月2号  1900-01-05 02:52:48            2022年5-14
95             2020年5月5日           2020年5月10日  2022-05-09 00:00:00
96            2020年4月10日           2020年4月10日  2022-04-09 00:00:00
99   2020-05-11 00:00:00  2020-05-11 00:00:00  2022-05-10 00:00:00
121           2020年4月15号  2020-03-01 00:00:00           2023年2月28日
178           2020年4月30日              2020年4月  2022-02-28 00:00:00
180           2020年5月18日  2020-05-20 00:00:00  2022-05-19 00:00:00
186           2020年4月28日           2020年4月30日  2022-04-29 00:00:00
196           2020年5月18号  2020-05-20 00:00:00  2022-05-19 00:00:00
197           2020年3月18号           2020年3月18日  2022-02-28 00:00:00
231             2020-5-8  2020-05-08 00:00:00             2023-5-8

Из print(df.loc[mask.any(axis=1), mask.any().reindex(df.columns, fill_value=False)].to_dict('l')):

{'date1': ['2020.4.20', '2020年4月23日', '2020年4月12日', '2020年5月6日', datetime.datetime(2020, 3, 20, 0, 0), datetime.datetime(2020, 3, 15, 0, 0), datetime.datetime(2020, 4, 1, 0, 0), datetime.datetime(2020, 4, 3, 0, 0), datetime.datetime(2020, 4, 14, 0, 0), '2020年4月3日', datetime.datetime(2020, 4, 30, 0, 0), '2020年5月7日', '2020年5月2号', '2020年5月5日', '2020年4月10日', datetime.datetime(2020, 5, 11, 0, 0), '2020年4月15号', '2020年4月30日', '2020年5月18日', '2020年4月28日', '2020年5月18号', '2020年3月18号', '2020-5-8'], 'date2': [datetime.datetime(2020, 5, 20, 0, 0), datetime.datetime(2020, 5, 1, 0, 0), '2020年4月20日', datetime.datetime(2020, 5, 7, 0, 0), datetime.datetime(2020, 4, 1, 0, 0), datetime.datetime(2020, 3, 20, 0, 0), datetime.datetime(2020, 5, 1, 0, 0), datetime.datetime(2020, 4, 3, 0, 0), datetime.datetime(2020, 4, 20, 0, 0), datetime.datetime(2020, 4, 18, 0, 0), '2020年5月10号', datetime.datetime(2020, 5, 6, 0, 0), datetime.datetime(1900, 1, 5, 2, 52, 48), '2020年5月10日', '2020年4月10日', datetime.datetime(2020, 5, 11, 0, 0), datetime.datetime(2020, 3, 1, 0, 0), '2020年4月', datetime.datetime(2020, 5, 20, 0, 0), '2020年4月30日', datetime.datetime(2020, 5, 20, 0, 0), '2020年3月18日', datetime.datetime(2020, 5, 8, 0, 0)], 'date3': [datetime.datetime(2023, 5, 19, 0, 0), datetime.datetime(2022, 4, 30, 0, 0), datetime.datetime(2022, 4, 19, 0, 0), '2022年5月8日', datetime.datetime(2022, 3, 31, 0, 0), datetime.datetime(2021, 3, 19, 0, 0), datetime.datetime(2025, 4, 30, 0, 0), datetime.datetime(2022, 4, 2, 0, 0), datetime.datetime(2021, 4, 19, 0, 0), '2022年4月17日', datetime.datetime(2022, 5, 9, 0, 0), datetime.datetime(2021, 5, 5, 0, 0), '2022年5-14', datetime.datetime(2022, 5, 9, 0, 0), datetime.datetime(2022, 4, 9, 0, 0), datetime.datetime(2022, 5, 10, 0, 0), '2023年2月28日', datetime.datetime(2022, 2, 28, 0, 0), datetime.datetime(2022, 5, 19, 0, 0), datetime.datetime(2022, 4, 29, 0, 0), datetime.datetime(2022, 5, 19, 0, 0), datetime.datetime(2022, 2, 28, 0, 0), '2023-5-8']}

1 Ответ

1 голос
/ 28 мая 2020

Для поиска строки с неправильными датами можно немного изменить ваше решение - добавлено errors='coerce' в to_datetime для отсутствующих значений, если не анализируемые даты, а затем проверить отсутствующие значения на DataFrame.isna с any:

print (df)
   id       date1       date2       date3
0   1   2020-5-10   2020-5-18   2021-5-17
1   2   2020.4.20   2020/5/20   2023/5/19
2   4   2020年5月7日   2020年5月20   2023年5月19
3   5  2020年4月23日    2020/5/1   2022/4/30
4   6  2020年4月12日  2020年4月20日   2022/4/19
5   7   2020年5月8日   2020年5月8日   2022年5月8日
6   8   2020年5月3号   2020年5月8号     2022年5月 <- error
7  12  2020—05—10  2020—05—11  2021—05—10
8  13  2020—05—08  2020—05—15  2022—05—14
9  14  2020年3月15日  2020年3月15日  2023年3月14日


def date_manipulate(x):
    x = x.str.strip()
    x = x.str.replace(' ', '')
    x = x.str.replace('年', '-')
    x = x.str.replace('月', '-')
    x = x.str.replace('日', '')
    x = x.str.replace('号', '')
    x = x.str.replace('.', '-')
    x = x.str.replace('—', '-')
    x = pd.to_datetime(x, errors='coerce')
    return x

Также возможна функция упрощения:

def date_manipulate(x):
    x = x.replace([' ', '日', '号'], '', regex=True)
    x = x.replace(['年','月','—', '\.'], '-', regex=True)
    x = pd.to_datetime(x, errors='coerce')
    return x

date_cols = ['date1', 'date2', 'date3']

mask = df[date_cols].apply(date_manipulate).isna()
print (df.loc[mask.any(axis=1), mask.any().reindex(df.columns, fill_value=False)])

     date3
6  2022年5月
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...