Объединение двух фреймов данных и условное вычисление нового столбца с пользовательской функцией - остаются неконвертированные данные: t - PullRequest
0 голосов
/ 29 марта 2019

Я хотел бы создать столбец в dataFrame, который будет результатом двух других

. В приведенном ниже примере были созданы два dataFrames: df1 и df2.

Затем третийБыл создан dataFrame, который является соединением первых двух.В этом df3 столбец «Даты» был изменен на тип dateTime.

После этого был создан столбец «DateMonth», месяц которого был извлечен из столбца «Даты».

import pandas as pd
import numpy  as np
from datetime import datetime

# df1 and df2:
id_sales   = [1, 2, 3, 4, 5, 6]
col_names  = ['Id', 'parrotId', 'Dates']
df1        = pd.DataFrame(columns = col_names)
df1.Id     = id_sales
df1.parrotId = [1, 2, 3, 1, 2, 3]
df1.Dates  = ['1900-01-01', '2012-08-20', '1900-01-01', '1900-01-01', '2016-02-21', '2012-08-21']

col_names2 = ['parrotId', 'months']
df2        = pd.DataFrame(columns = col_names2)
df2.parrotId = [1, 2, 3]
df2.months = [('Mar,Jun,Sept,Dec'), ('Mar,Jun,Sept,Dec'), ('Mar,Jun,Sept,Dec')]

df3 = pd.merge(df1, df2, on = 'parrotId')
df3.Dates = pd.to_datetime(df3['Dates'], format = "%Y-%m-%d")

С помощью пользователя Lukas была создана следующая функция

def matched(row):
    if type(row['months'])==str:
        # for the case ('Feb, Mar, Apr') - get numerical representation of month from your string and return True if the 'Dates' value matches with some list item
        return row['Dates'].month in [datetime.strptime(mon.strip()[:3], '%b').month for mon in row['months'].split(',')]  
    else:
        # for numbers - return True if months match
        return row['Dates'].month==row['months']

Применение:

df3['DateMonth'] = df3.apply(matched, axis=1).astype(int)

В примере выше у меня не было проблем.Но при репликации в моем наборе данных я получил следующее сообщение об ошибке:

ValueError: ('остаются не преобразованные данные: t', 'произошло с индексом 16772')

СтолбецДаты имеют тип Имя: Дата, тип: datetime64 [нс]

Индекс 16772:

months     Mar,Jun,Sept,Dec
Dates      2015-07-31 00:00:00

Индекс 16771:

months     Jan,Apr,Jul,Oct
Dates      2013-01-01 00:00:00

Уникальные значения:

array([0, 'Jan,Apr,Jul,Oct', 'Feb,May,Aug,Nov', 'Mar,Jun,Sept,Dec'],
      dtype=object)

Как решить эту ошибку?

1 Ответ

1 голос
/ 29 марта 2019

Входные данные неверны.

Убедитесь, что datetime.strptime() получает хорошие входные данные. Например, strptime %b требуется трехбуквенный месяц.

В match() уберите пробел из разбиения и нарежьте результат до трех символов.

        return row['Dates'].month in [datetime.strptime(mon.strip()[:3], '%b').month for mon in row['months'].split(',')]        

Рабочий пример

import pandas as pd
import numpy  as np
from datetime import datetime

# df1 and df2:
id_sales   = [1, 2, 3, 4, 5, 6]
col_names  = ['Id', 'parrotId', 'Dates']
df1        = pd.DataFrame(columns = col_names)
df1.Id     = id_sales
df1.parrotId = [1, 2, 3, 1, 2, 3]
df1.Dates  = ['2012-12-25', '2012-08-20', '2013-07-23', '2014-01-14', '2016-02-21', '2015-10-31']

col_names2 = ['parrotId', 'months']
df2        = pd.DataFrame(columns = col_names2)
df2.parrotId = [1, 2, 3]
df2.months = [12, ('Febt,Mar,Mar'), 0]

df3 = pd.merge(df1, df2, on = 'parrotId')
df3.Dates = pd.to_datetime(df3['Dates'], format = "%Y-%m-%d")
# determine if df3['Dates'].month is zero or one offset (is one)
#print(df3['Dates'].apply(lambda x: x.month))

#exit(0)

def matched(row):
    #print("Will process row", row)
    if type(row['months'])==str:
        # for the case ('Feb, Mar, Apr') - get numerical representation of month from your string and return True if the 'Dates' value matches with some list item
        print (row['Dates'].month)
        # determine if datetime.strptime is zero or one offset (is one)
        # print ([datetime.strptime(mon.strip()[:3], '%b').month for mon in row['months'].split(',')])
        return row['Dates'].month in [datetime.strptime(mon.strip()[:3], '%b').month for mon in row['months'].split(',')]        
    else:
        # for numbers - return True if months match
        return row['Dates'].month==row['months']

df3['DateMonth'] = df3.apply(matched, axis=1).astype(int)

datetime.strptime('Mar'[:4], '%b').month

print (df3)

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