Как преобразовать столбец в фрейме данных pandas во время данных? - PullRequest
0 голосов
/ 30 октября 2019

У меня есть документ CSV, пример ниже:

oci,citing,cited,creation,timespan,journal_sc,author_sc
0200100000236252421370109080537010700020300040001-020010000073609070863016304060103630305070563074902,"10.1002/pol.1985.170230401","10.1007/978-1-4613-3575-7_2",1985-04,P2Y,no,no

Есть 2 столбца, представляющих даты, я хочу изменить тип столбца со строки на datetime формат.

Столбец creation (строка) является датой создания и может быть дополнительно указан в трех формах:

  1. "гггг-мм-дд" (например, "2019-09-20"")
  2. " гггг-мм "(например," 2019-09 ")
  3. " гггг "(например," 2019 ")

столбец timespan(строка): представляется в виде PnYnMnD, где P - буквальное значение, с которого начинается выражение, nY - количество лет, за которыми следует литерал Y, nM - числомесяцы, за которыми следует литерал M, nD - количество дней, за которыми следует литерал D, где любое из этих чисел и соответствующие им обозначения могут отсутствовать, если они равны 0. Знак минус может появляться передP для указания отрицательной продолжительности.

Я пытаюсь изменить тип столбца со строки на datetime формат, используя pd.to_datetime()функция:

def do_process(f_path):
    global my_ocan

    my_ocan = pd.read_csv(f_path, names=['oci', 'citing', 'cited', 'creation', 'timespan', 'journal_sc', 'author_sc'], parse_dates = ['creation', 'timespan'])
    my_ocan['timespan'] = pd.to_datetime(my_ocan['timespan'], format='%Y%m%d', errors='ignore', yearfirst=True)
    my_ocan['creation'] = pd.to_datetime(my_ocan['creation'], format='%Y%m%d', errors='ignore', yearfirst=True)
    #print(my_ocan['citing'])
    print(my_ocan.info())

    return my_ocan

При выполнении print(my_ocan.info()) я получаю «214 ненулевой объект» вместо datetime. Что мне не хватает? В чем проблема?

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 214 entries, 0 to 213
Data columns (total 7 columns):
oci           214 non-null object
citing        214 non-null object
cited         214 non-null object
creation      214 non-null object
timespan      214 non-null object
journal_sc    214 non-null object
author_sc     214 non-null object
dtypes: object(7)

Спасибо и хорошего вам дня :))

1 Ответ

0 голосов
/ 30 октября 2019

В вашем коде необходимо решить несколько проблем.

Во-первых, обратите внимание, что в вашем файле .csv первый столбец:

oci,citing,cited,creation,timespan,journal_sc,author_sc

Итак, когда выпри построении базы данных с pd.read_csv первая строка вашего информационного кадра будет первой строкой вашего .csv файла. В итоге ваш фрейм данных выглядит так:

                                                 oci  ...  author_sc
0                                                oci  ...  author_sc
1  0200100000236252421370109080537010700020300040...  ...         no

вместо:

[2 rows x 7 columns]
                                                 oci  ... author_sc
1  0200100000236252421370109080537010700020300040...  ...        no

Не думаю, что вы этого хотите.

Вы также подавляете ошибки с помощью pd.to_datetime что не здорово. После удаления errors='ignore' вы заметите, что преобразование в datetime завершилось неудачно, поскольку ввод не соответствует формату '%Y%m%d'.

И, конечно, это не так, поскольку ваш столбец creation:

0    creation
1     1985-04

И первая строка "creation", которая не соответствует '%Y%m%d'.

Во-вторых, формат даты должен быть '%Y-%m-%d', поскольку даты имеют формат ГГГГ-ММ-ДД, а не ГГГГММДД. (Осторожно, потому что, когда, например, в вашем формате есть дни, а во входных данных нет, к дате добавляется день).

В-третьих, значения timespan не являются датами, онипериоды (период Java, если я не ошибаюсь), поэтому использование pd.to_datetime для них не работает. Я не нашел функции python, которая выполняет преобразование для вас, так что вам, возможно, придется выполнять работу самостоятельно в старом добром стиле или разбираться в библиотеках Python.

В-четвертых, как документация говорит, что pd.to_datetime устарела, так что вы бы лучше держались в стороне и использовали, например, datetime.strptime, который выполняет очень похожую работу.

Наконец, вот рабочая версия вашегокод:

 def do_process(f_path):
     global my_ocan

     my_ocan = pd.read_csv(f_path, names=['oci', 'citing', 'cited', 'creation', 'timespan', 'journal_sc', 'author_sc'], parse_dates = ['creation', 'timespan'])
     my_ocan = my_ocan.iloc[1:]  # to remove the first row
     my_ocan['creation'] = pd.to_datetime(my_ocan['creation'], format="%Y-%m-%d", yearfirst=True)
     # Period parsing on my_ocan['timespan']
     print(my_ocan.info())

     return my_ocan

Какие выходы:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1 entries, 1 to 1
Data columns (total 7 columns):
oci           1 non-null object
citing        1 non-null object
cited         1 non-null object
creation      1 non-null datetime64[ns]
timespan      1 non-null object
journal_sc    1 non-null object
author_sc     1 non-null object
dtypes: datetime64[ns](1), object(6)

Уведомление creation имеет тип datetime64[ns] сейчас.

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