#python #python-3.x #pandas #optimization #data-analysis
#python #python-3.x #pandas #оптимизация #анализ данных
Вопрос:
У меня есть фрейм данных pandas, в котором есть два столбца. Первый столбец представляет name
элемент, а второй столбец представляет некоторые из его свойств, которые кодируются как целые числа. Элементу может соответствовать несколько свойств. Вот пример
name ids
0 A 147 616 813
1 B 51 616 13 813
2 C 776
3 D 51 671 13 813 1092
4 E 13 404 492 903 1093
Существует 300 таких уникальных свойств, закодированных как целые числа, а затем представленных в виде строк в id
столбце. Чего я хочу достичь:
- Для каждого идентификатора найдите строки, в которых он встречается. Например, чтобы проверить наличие
id
13, я бы извлек строки1, 3 and 4
. - Каковы все уникальные идентификаторы, которые пришли с этим идентификатором в нашем наборе данных? Например, я бы сказал, что для идентификатора
13: [51, 616, 813, 671, 1092, 404, 492, 903, 1093]
- Как только у нас будут сгруппированные строки для каждого идентификатора, как я могу сравнить, находится ли данный идентификатор в этой группе или нет? Например, я хочу проверить,
52
когда-либо встречался ли идентификатор с id13
, и если да, то где и сколько раз?
Я долго думал об этом, но не смог предложить эффективный метод для получения первых двух и эффективный способ, а также DS для 3). Пожалуйста, помогите!
Ответ №1:
Вот предложение для трех функций:
import pandas as pd
# first we create the data
data = pd.DataFrame({'name': ['A','B','C','D','E'],
'ids': ['147 616 813','51 616 13 813','776','51 671 13 813
1092','13 404 492 903 1093']})
def func1(num, series):
# num must be an int
# series a Pandas series
tx = series.apply(lambda x: True if str(num) in x.split() else False)
output_list = series.index[tx].tolist()
return output_list
def func2(num, series):
# num must be an int
# series a Pandas series
series = series.iloc[func1(num, series)]
series = series.apply(lambda x: x.split()).tolist()
output_list = set([item for sublist in series for item in sublist])
output_list.remove(str(num))
return list(output_list)
def func3(num1,num2,series):
# num1 must be an int
# num2 must be an int
# series a Pandas series
if str(num1) in func2(num2, series):
num1_index = func1(num1, series)
num2_index = func1(num2, series)
return list(set(num1_index) amp; set(num2_index))
else:
return 'no match'
и тогда вы могли бы их протестировать:
func1(13, data['ids'])
func2(13, data['ids'])
func3(13,51,data['ids'])
Ответ №2:
Решение без использования какого-либо цикла for
import pandas as pd
import numpu as np
df = pd.DataFrame({'name':'A B C D E'
.split(),'ids':['147 616 813','51 616 13 813','776','51 671 13 813 1092','13 404 492 903 1093']})
#Every input of i_d to functions in int
#to get indexes where id occurs
def rows(i_d):
i_d = str(i_d)
pattern1 = "[^0-9]" i_d "[^0-9]"
pattern2 = i_d "[^0-9]"
pattern3 = "[^0-9]" i_d
mask = df.ids.apply(lambda x: True if (len(re.findall(pattern1,x)) > 0) | (len(re.findall(pattern2,x))) | (len(re.findall(pattern3,x)) > 0) else False)
return df[mask].index.tolist()
#to get other ids occuring with the id in discussion
def colleagues(i_d):
i_d = str(i_d)
df.loc[rows(i_d),'temp'] = 1
k =list(set(df.groupby('temp').ids.apply(lambda x: ' '.join(x)).iloc[0].split()))
k.remove(i_d)
df.drop('temp',axis=1,inplace=True)
return k
#to get row indexes where 2 ids occur together
def third(i_d1,i_d2):
i_d1 = str(i_d1)
i_d2 = str(i_d2)
common_rows = list(np.intersect1d(rows(i_d1),rows(i_d2)))
if len(common_rows) > 0:
return print('Occured together at rows ',common_rows)
else:
return print("Didn't occur together")
Комментарии:
1. Спасибо за ответ, но
for
цикл нигде не является эффективным способом2. @mlRocks Ознакомьтесь с этим обновленным кодом, надеюсь, это поможет 🙂