2016-06-06 6 views
1

У меня есть такой кадр данных.Применение одинакового вычисления для каждого элемента данных в python

  user tag1 tag2 tag3 
0 Roshan ghai 0.0 1.0 1.0 
1 mank nion 1.0 1.0 2.0 
2 pop rajuel 2.0 0.0 1.0 
3 random guy 2.0 1.0 1.0 

Мне нужно применить расчет для каждой строки. который для каждого элемента x

x =((specific tag's count for that user ##that element itself##))/ max no. of count of that tag ##max value of that column##)) * (ln(no. of total user ##lenth of df##)/(no. of of user having that tag ##no. of user having non 0 count for that particular tag or column ##)) 

Я использовал ## для описания этого конкретного значения. Я должен сделать это для каждого элемента dataframe, что является наиболее эффективным способом для этого, поскольку у меня большой нет. элементов. Я использую python2.7. выход:

  user tag1 tag2 tag3 
0 Roshan ghai  0 .287  0 
1 mank nion .143 .287  0 
2 pop rajuel .287  0  0 
3 random guy .287 .287  0 

Я только использовал формулу, которую я написал, как для Mank Nion и tag1 х = ((1,0) /2.0) * (п (4/3) = .143

.
+0

Вы можете добавить нужный вывод и как считать первое значение этого вывода? – jezrael

+0

@jezrael Я добавил вывод, подсчет для этого пользователя - это то, что у меня есть в dataframe для этого пользователя & tag, как для mank nion & tag1, это 1.0. любые другие сомнения ?. пожалуйста, помогите –

+0

@jezrael, пожалуйста, помогите. –

ответ

1

Вы можете сначала выбрать все значения без первой колонки на ix. Затем используйте max, sum из не являющихся 0 значений и numpy.log:

import pandas as pd 
import numpy as np 

print (df.ix[:, 'tag1':].max()) 
tag1 2.0 
tag2 1.0 
tag3 2.0 
dtype: float64 

print ((df.ix[:, 'tag1':] != 0).sum()) 
tag1 3 
tag2 3 
tag3 4 
dtype: int64 

df.ix[:, 'tag1':] = (df.ix[:, 'tag1':]/df.ix[:, 'tag1':].max() * 
        (np.log(len(df)/(df.ix[:, 'tag1':] != 0).sum()))) 

print (df) 
      user  tag1  tag2 tag3 
0 Roshan-ghai 0.000000 0.287682 0.0 
1 mank-nion 0.143841 0.287682 0.0 
2 pop-rajuel 0.287682 0.000000 0.0 
3 random-guy 0.287682 0.287682 0.0 

Другое решение с iloc:

df1 = df.iloc[:, 1:] 
df.iloc[:, 1:] = (df1/df1.max() * (np.log(len(df)/(df1 != 0).sum()))) 
print (df) 
      user  tag1  tag2 tag3 
0 Roshan-ghai 0.000000 0.287682 0.0 
1 mank-nion 0.143841 0.287682 0.0 
2 pop-rajuel 0.287682 0.000000 0.0 
3 random-guy 0.287682 0.287682 0.0 
1

вы можете попробовать это:.

import io 
temp = u"""   user tag1 tag2 tag3 
0 Roshan-ghai 0.0 1.0 1.0 
1 mank-nion 1.0 1.0 2.0 
2 pop-rajuel 2.0 0.0 1.0 
3 random-guy 2.0 1.0 1.0""" 
df = pd.read_csv(io.StringIO(temp), delim_whitespace=True) 

maxtag1 = df.tag1.max() 
maxtag2 = df.tag2.max() 
maxtag3 = df.tag3.max() 
number_users = len(df) 
number_users_tag1 = len(df[df['tag1']!=0]) 
number_users_tag2 = len(df[df['tag2']!=0]) 
number_users_tag3 = len(df[df['tag3']!=0]) 
liste_values = [maxtag1,maxtag2,maxtag3,number_users,number_users_tag1,number_users_tag2,number_users_tag3] 

Затем вы создаете функцию, которая принимает в качестве входных данных вашей строки и эти значения и который выводит нужные три значения и использовать apply:

output = df.apply(lambda x: yourfunction(x, list_values)) 
+0

используя этот метод для 200 пользователей не будет так хорошо, я думаю. Есть функция, которая может сделать это коротким и быстрым, надеюсь. –

+0

Я делаю это для dataframes с несколькими десятками тысяч строк, и это занимает менее одной минуты. Так что это довольно эффективно, но далеки от оптимального. – ysearka