шагая через pandas фрейм данных - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть датафрейм в форме

date_time                                                            uids
2018-10-16 23:00:00                                                 1000,1321,7654,1321
2018-10-16 23:10:00                                                 7654
2018-10-16 23:20:00                                                  NaN
2018-10-16 23:30:00                                                 7654,1000,7654,1321,1000
2018-10-16 23:40:00                                                 691,3974,3974,323
2018-10-16 23:50:00                                                  NaN
2018-10-17 00:00:00                                                  NaN
2018-10-17 00:10:00                                                  NaN
2018-10-17 00:20:00                                                 27,33,3974,3974,7665,27 

Это очень большой фрейм данных, содержащий 5-минутный интервал времени и количество появлений идентификаторов за эти интервалы времени.

Я хочу перебирать эти строки DataFrame 6 за раз (что соответствует 1 часу) и создавать DataFrame, содержащий идентификатор и количество раз, которое каждый идентификатор появляется в течение этого времени.

Ожидаемый результат - один кадр данных в час. , Например, в приведенном выше случае датафрейм для часа 23-00 будет иметь такую ​​форму

uid   1   2   3   4   5   6

1000  1   0   0   2   0  0
1321  2   0   0   1   0  0

и т. Д.

Как я могу сделать это эффективно?

Ответы [ 3 ]

1 голос
/ 01 февраля 2020

Вы можете использовать функцию crosstab:

df['uids'] = df['uids'].str.split(',')
df = df.explode('uids')
df['date_time'] = df['date_time'].dt.minute.floordiv(10).add(1)
pd.crosstab(df['uids'], df['date_time'], dropna=False)

Выход:

date_time  1  2  3  4  5  6
uids                       
1000       1  0  0  2  0  0
1321       2  0  0  1  0  0
27         0  0  2  0  0  0
323        0  0  0  0  1  0
33         0  0  1  0  0  0
3974       0  0  2  0  2  0
691        0  0  0  0  1  0
7654       1  1  0  2  0  0
7665       0  0  1  0  0  0
1 голос
/ 01 февраля 2020

Мы можем добиться этого, извлекая минуты из вашего столбца даты и времени. Затем, используя pivot_table, вы получите широкий формат:

df['date_time'] = pd.to_datetime(df['date_time'])

df['minute'] = df['date_time'].dt.minute // 10

piv = (df.assign(uids=df['uids'].str.split(','))
         .explode('uids')
         .pivot_table(index='uids', columns='minute', values='minute', aggfunc='size')
      )
minute    0    1    2    3    4
uids                           
1000    1.0  NaN  NaN  2.0  NaN
1321    2.0  NaN  NaN  1.0  NaN
27      NaN  NaN  2.0  NaN  NaN
323     NaN  NaN  NaN  NaN  1.0
33      NaN  NaN  1.0  NaN  NaN
3974    NaN  NaN  2.0  NaN  2.0
691     NaN  NaN  NaN  NaN  1.0
7654    1.0  1.0  NaN  2.0  NaN
7665    NaN  NaN  1.0  NaN  NaN
1 голос
/ 01 февраля 2020

У меня нет точного решения, но вы можете создать сводную таблицу: идентификаторы по индексу и datetime по столбцам. Тогда вам просто нужно выбрать столбцы, которые вы хотите.

import pandas as pd
import numpy as np

df = pd.DataFrame(
{
    "date_time": [
        "2018-10-16 23:00:00",
        "2018-10-16 23:10:00",
        "2018-10-16 23:20:00",
        "2018-10-16 23:30:00",
        "2018-10-16 23:40:00",
        "2018-10-16 23:50:00",
        "2018-10-17 00:00:00",
        "2018-10-17 00:10:00",
        "2018-10-17 00:20:00",
    ],
    "uids": [
        "1000,1321,7654,1321",
        "7654",
        np.nan,
        "7654,1000,7654,1321,1000",
        "691,3974,3974,323",
        np.nan,
        np.nan,
        np.nan,
        "27,33,3974,3974,7665,27",
    ],
}
)

df["date_time"] = pd.to_datetime(df["date_time"])

df = (
    df.set_index("date_time") #do not use set_index if date_time is current index
    .loc[:, "uids"]
    .str.extractall(r"(?P<uids>\d+)")
    .droplevel(level=1)
) # separate all the ids

df["number"] = df.index.minute.astype(float) / 10 + 1 # get the number 1 to 6 depending on the minutes

df_pivot = df.pivot_table(
    values="number", 
    index="uids", 
    columns=["date_time"], 
) #dataframe with all the uids on the index and all the datetimes in columns. 

Вы можете применить это ко всему фрейму данных или только к подмножеству, содержащему 6 строк. Затем вы переименовываете свои столбцы.

...