2017-02-02 3 views
1

У меня есть следующий питон панд dataframe:Python Панды Рассчитать процент возврата в категорию

  | Number of visits per year | 
user id | 2013 | 2014 | 2015 | 2016 | 
    A   4  3  6  0  
    B   3  0  7  3 
    C   10  6  3  0 

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

Это конечный результат я ищу:

  |  Number of visits in the year  | 
Year | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 
2014  7% 3% 4% 15% 6% 7% 18% 17% 3% 2% 
2015  3% .... 
2016 

Так на основе вышеизложенного можно сказать, что 15% клиентов, которые посетили магазин в 4 раза в 2013 году, вернулся в магазин в 2014 году .

спасибо.

ОБНОВЛЕНИЕ: Это то, что я сделал, может быть, есть лучший путь через петлю?

За каждый год, у меня был файл CSV, как это:

user_id | NR_V 
    A   4  
    B   3  
    C   10 

NR_V обозначает количество посещений.

Поэтому я загрузил каждый csv как свой собственный df, и у меня были df_2009, df_2010, ... до df_2016.

Для каждого файла я добавил столбец столбца с 0/1, если они совершают покупки в следующем году.

df_2009['shopped2010'] = np.where(df_2009['user_ID'].isin(df_2010['user_ID']), 1, 0) 

Затем я поворачивал каждый информационный кадр.

pivot_2009 = pd.pivot_table(df_2009,index=["NR_V"],aggfunc={"NR_V":len, "shopped2010":np.sum}) 

Далее, для каждого dataframe я создал новый dataframe с колонкой вычисления процента по количеству посещений.

p_2009 = pd.DataFrame() 
p_2009['%returned2010'] = (pivot_2009['shopped2010']/pivot_2009['NR_V'])*100 

Наконец, я объединил все эти данные в один.

dfs = [p_2009, p_2010, p_2011, p_2012, p_2013, p_2014, p_2015 ] 
final = pd.concat(dfs, axis=1) 

ответ

2

Рассмотрим посещения образца dataframe df

df = pd.DataFrame(
    np.random.randint(1, 10, (100, 5)), 
    pd.Index(['user_{}'.format(i) for i in range(1, 101)], name='user id'), 
    [ 
     ['Number of visits per year'] * 5, 
     [2012, 2013, 2014, 2015, 2016] 
    ] 
) 

df.head() 

enter image description here


Вы можете применить pd.value_counts с параметром normalize=True.
Кроме того, поскольку запись 8 представляет собой 8 отдельных посещений, она должна считаться 8 раз.Я буду использовать repeat для достижения этой цели до value_counts

def count_visits(col): 
    v = col.values 
    return pd.value_counts(v.repeat(v), normalize=True) 

df.apply(count_visits).stack().unstack(0) 

enter image description here

+0

Спасибо @piRSquared, но это только дает мне счет, а не проценты клиентов, которые вернулись в следующем году – jeangelj

+0

Спасибо, я сейчас пытаюсь это решение. – jeangelj

-1

Ниже вы найдете решение. В качестве примечания я вполне уверен, что это можно улучшить.


# step 0: create data frame 
df = pd.DataFrame({'2013':[4, 3, 10], '2014':[3, 0, 6], '2015':[6, 7, 3], '2016':[0, 3, 0]}, index=['A', 'B', 'C']) 

# container list of dataframes to be concatenated 
frames = [] 

# iterate through the dataframe one column at a time and determine its value_counts(freq table) 
for name, series in df.iteritems(): 
    frames.append(series.value_counts()) 

# Merge frequency table for all columns into a dataframe 
temp_df = pd.concat(frames, axis=1).transpose().fillna(0) 

# Find the key for the new dataframe (i.e. range for number of columns), and append missing ones 
cols = temp_df.columns 
min = cols.min() 
max = cols.max() 
for i in range(min, max): 
    if (not i in a): 
     temp_df[str(i)] = 0 

# Calculate percentage 
final_df = temp_df.div(temp_df.sum(axis=1), axis=0) 

+0

Спасибо, к сожалению, итерация функция убивает мое ядро ​​мгновенно – jeangelj

+0

Очень хотелось бы знать, как сделать это без итерации. – kuriouscoder

+0

Когда я запустил его, я обнаружил, что «python.exe перестает работать» - поток сохранения истории попадает в непредвиденную ошибку (AttributeError («длинный» объект не имеет атрибута «приобретать»,)). История не будет записываться в база данных. – jeangelj

0

Я использовал значение индекса каждого посетителя и проверяется, если же значение индекса (ака же vistor_ID) был более 0 следующая год. Затем он был добавлен в словарь в виде True или False, который вы могли бы использовать для диаграммы. Я также сделал два списка (times_returned и return_at_all) для дополнительной обработки данных.

import pandas as pd 

# Part 1, Building the dataframe. 

df = pd.DataFrame({ 
        'Visitor_ID':[1,2,3], 
        '2010'  :[4,3,10], 
        '2011'  :[3,0,6], 
        '2012'  :[6,7,3], 
        '2013'  :[0,3,0]  
        }) 

df.set_index("Visitor_ID", inplace=True) 

# Part 2, preparing the required variables. 

def dictionary (max_visitors): 
    dictionary={} 
    for x in range(max_visitors): 
     dictionary["number_{}".format(x)] = [] 
# print(dictionary) 
    return dictionary 

# Part 3, Figuring out if the customer returned.    

def compare_yearly_visits(current_year, next_year):  
    index = 1 
    years = df.columns 
    for x in df[current_year]: 
#  print (df[years][current_year][index], 'this year.') 
#  print (df[years][next_year][index], 'Next year.') 
     how_many_visits = df[years][current_year][index] 
     did_he_return = df[years][next_year][index] 

     if did_he_return > 0: 
      # If the visitor returned, add to a bunch of formats: 
      returned_at_all.append([how_many_visits, True]) 
      times_returned.append([how_many_visits, did_he_return]) 
      dictionary["number_{}".format(x)].append(True) 
     else: 
      ## If the visitor did not return, add to a bunch of formats: 
      returned_at_all.append([how_many_visits, False]) 
      dictionary["number_{}".format(x)].append(False) 

     index = index +1 

# Part 4, The actual program: 
highest_amount_of_visits = 11 # should be done automatically, max(visits)?   
relevant_years = len(df.columns) -1 
times_returned = [] 
returned_at_all = [] 

dictionary = dictionary(highest_amount_of_visits) 
for column in range(relevant_years): 
# print (dictionary) 
    this_year = df.columns[column] 
    next_year = df.columns[column+1] 
    compare_yearly_visits(this_year, next_year) 
    print ("cumulative dictionary up to:", this_year,"\n", dictionary) 
+0

Спасибо, я сейчас пытаюсь это решение. – jeangelj

Смежные вопросы