Векторизация pandas dataframe применяет функцию для пользовательской функции в python - PullRequest
0 голосов
/ 16 октября 2018

Я хочу вычислить неделю месяца для указанной даты.Для вычисления недели месяца я использую пользовательскую функцию.

Фрейм входных данных:

Input data frame

Фрейм выходных данных:

Output dataframe

Вот что я пробовал:

from math import ceil
def week_of_month(dt):
    """ 
       Returns the week of the month for the specified date.
    """

    first_day = dt.replace(day=1)

    dom = dt.day
    adjusted_dom = dom + first_day.weekday()

    return int(ceil(adjusted_dom/7.0))

После этого

import pandas as pd

df = pd.read_csv("input_dataframe.csv")
df.date = pd.to_datetime(df.date)
df['year_of_date'] = df.date.dt.year
df['month_of_date'] = df.date.dt.month
df['day_of_date'] = df.date.dt.day


wom = pd.Series()

# worker function for creating week of month series
def convert_date(t):
    global wom
    wom = wom.append(pd.Series(week_of_month(datetime.datetime(t[0],t[1],t[2]))), ignore_index = True)

# calling worker function for each row of dataframe
_ = df[['year_of_date','month_of_date','day_of_date']].apply(convert_date, axis = 1)

# adding new computed column to dataframe
df['week_of_month'] = wom
# here this updated dataframe should look like Output data frame.

Для каждой строки фрейма данных он вычисляет неделю месяца, используя данную функцию.Это делает вычисления медленнее, поскольку фрейм данных увеличивается до большего количества строк.Потому что в настоящее время у меня более 10 миллионов строк.

Я ищу более быстрый способ сделать это.Какие изменения можно внести в этот код, чтобы векторизовать эту операцию во всех строках?

Заранее спасибо.

Редактировать: Что сработало для меня после прочтения ответов, ниже кода,

first_day_of_month = pd.to_datetime(df.date.values.astype('datetime64[M]'))
df['week_of_month'] = np.ceil((df.date.dt.day + first_day_of_month.weekday) / 7.0).astype(int)

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Метод week_of_month может быть векторизован.Может быть полезным не выполнять преобразование в объекты даты и времени, а вместо этого использовать только методы pandas.

first_day_of_month = df.date.to_period("M").to_timestamp()
df["week_of_month"] = np.ceil((data.day + first_day_of_month.weekday) / 7.0).astype(int)
0 голосов
/ 16 октября 2018

сразу же, даже не вдаваясь в ваш код и не упоминая о проблемах X / Y и т. Д .:
попробуйте получить список уникальных дат, я уверен, что в 10M строках у вас более одногодубликат.

Шаги:

  1. создайте 2-й df, который содержит только нужные вам столбцы и не содержит дубликатов (drop_duplicates)
  2. , запустите вашу функцию на маленьком фрейме данных
  3. объединить большие и маленькие dfs
  4. (опционально) отбросить маленькое
...