Как рассчитать количество дней между этапами в этой пф Python? - PullRequest
0 голосов
/ 21 марта 2019
df = pd.DataFrame({'Campaign ID':[48464,48464,48464,48464,26380,26380,22676,39529,39529,46029,46029,46029,17030,46724,46724,39379,39379,39379],
'Campaign stage':["Lost","Developing","Discussing","Starting","Discussing", "Starting","Developing",    "Discussing","Starting","Developing",   "Discussing","Starting","Developing",   "Developing","Discussing","Lost",   "Developing","Discussing"],
'Stage Number':[-1, 3,  2,  1,  2,  1,  3,  2,  1,  3,  2,  1,  3,  3,  2,  -1, 3,  2],
'Campaign Date':["2/8/2019","1/9/2019","1/3/2019","3/3/2018","2/14/2019","12/5/2018","7/25/2018","6/8/2018","3/4/2018","12/8/2018","9/9/2018","5/31/2018","6/7/2018","3/27/2018","1/6/2018","2/15/2019","12/15/2018","9/4/2018"]})

pvt = pd.pivot_table(df,values=['Campaign stage'],index=['Campaign ID','Campaign stage','Stage Number','Campaign Date'],aggfunc='count')
pvt.sort_values(['Campaign ID','Campaign Date'],ascending=[True,False])

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

Из-за качества данных этапы кампании не соответствуют друг другу.Поэтому для кампаний, не имеющих двух этапов «начало» и «обсуждение», я хочу установить значение 0.

Я создал сводную таблицу данных и отсортировал по убыванию даты кампании.Но я не знаю, что делать дальше.

Заранее спасибо за помощь.

Ответы [ 3 ]

0 голосов
/ 21 марта 2019
df['Campaign Date'] =  pd.to_datetime(df['Campaign Date'],format='%m/%d/%Y')
compare= {}
for ids,gp in df.groupby('Campaign ID'):
    try:
        compare[ids]= gp.loc[gp['Campaign stage']=='Discussing']['Campaign Date'].iloc[0] - gp.loc[gp['Campaign stage']=='Starting']['Campaign Date'].iloc[0]
    except:
        compare[ids] =0

df['new_col'] = df['Campaign ID'].apply(lambda x:compare[x])
0 голосов
/ 21 марта 2019

Я не уверен, в какой форме вы хотите получить конечный результат, в приведенном ниже примере предполагается, что вы хотите получить его в новом фрейме данных.

Мы можем пойти по нескольким маршрутам, хотя я решил создать функцию ниже и разложить каждый шаг для ясности.

  • Шаг 1: обновите тип данных даты до datetime для сравнения
  • Шаг 2: вызвать функцию Шаг 2.1: определить пустой список для хранения наших значений cids и дней между starting и discussing
    • Шаг 2.2: Получите все уникальные cid и переберите каждый из них
    • Шаг 2.3: Проверьте, есть ли у cid обе стадии, которые нас интересуют
      • Шаг 2.3.1: если не присвоить 0 этому cid
      • Шаг 2.3.2: иначе вычислите разницу между discussing и starting
    • Шаг 2.4: создайте наш новый фрейм данных и верните его
    • Шаг 2.5: Используя df.loc создайте и рассчитайте наш средний дневной индекс

код

# First we need to modify your data type to compare the dates
df['Campaign Date'] = pd.to_datetime(df['Campaign Date'])

df_days = getDays(df)

# We create a new index called 'Average' that will assign values to the days column
df_days.loc['Average','days'] = df_days.days.mean()

def getDays(df):
    days = list()
    cids = list()

    for cid in df['Campaign ID'].unique():
        stages = df[(df['Campaign ID'] == cid) & 
                    (df['Campaign stage'].str.lower().isin(['discussing', 'starting']))]['Campaign stage'].unique()

        if len(stages) < 2:
            d = 0
            c = cid

            days.append(d)
            cids.append(c)

        else:
            starting = df[(df['Campaign ID'] == cid) & (df['Campaign stage'].str.lower() == 'starting')]['Campaign Date'].dt.date.values
            discussing = df[(df['Campaign ID'] == cid) & (df['Campaign stage'].str.lower() == 'discussing')]['Campaign Date'].dt.date.values

            d = (discussing - starting)[0].days

            c = cid

            days.append(d)
            cids.append(c)


    dff = pd.DataFrame({
        'cids': cids,
        'days': days
    })          

    return dff

Out

        cids    days
0       48464.0 306.00
1       26380.0 71.00
2       22676.0 0.00
3       39529.0 96.00
4       46029.0 101.00
5       17030.0 0.00
6       46724.0 0.00
7       39379.0 0.00
Average NaN   71.75
0 голосов
/ 21 марта 2019

Вот мое предложение, начиная с вашего df:

df['Campaign Date'] = pd.to_datetime(df['Campaign Date'])
df = df[df['Campaign stage'].isin(['Starting', 'Discussing'])]

pvt = pd.pivot_table(df,values=['Campaign stage'],index=['Campaign ID','Campaign stage','Stage Number','Campaign Date'],aggfunc='count')
pvt = pvt.sort_values(['Campaign ID','Campaign Date'],ascending=True).reset_index(level=3)

pvt.groupby(level=0).diff().sum(level=0)

Вывод будет:

Campaign ID - Campaign Date
26380   71 days
39379   0 days
39529   96 days
46029   101 days
46724   0 days
48464   306 days

Если то, что вы ищете, является общим значением:

pvt.groupby(level=0).diff().sum(level=0).mean()

Что такое:

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