Есть ли способ оптимизировать создание таблицы соединений в пандах?
Я хочу, чтобы мой код работал быстрее. Я только начал заниматься наукой о данных и решил заняться проектом. Я скачал информацию о смертях от COVID-19 в нашей стране, которую наше правительство сделало доступной для общественности, и сделал из нее файл csv. Вот как выглядела его структура:
table1
Я отформатировал эту таблицу, чтобы сделать ее более управляемой.
Вот структура, к которой я пришел: table2
Как видно из таблицы 1, у каждого человека было несколько заболеваний, и мне было любопытно, "насколько они связаны", поэтому я создал table3.
Где у нас есть все уникальные болезни в виде столбцов (в данном случае это было более 500 столбцов), и каждая строка представляет уникальное заболевание. Таким образом, мы получим стол 500X500. Итак, с учетом всего сказанного, давайте перейдем к моему вопросу: как я могу сделать свой код, который приведет к более оптимальному table3, чем сейчас, потому что для его компиляции требуется слишком много времени (около 240 секунд с 500 уникальными болезней). Вот мой код:
import pandas as pd
from operator import add
import time
start_time = time.time()
#Columns:Id,Disease,Gender,Age
df=pd.read_csv('table2.csv')
headers=df.groupby('Disease').size().to_frame('size').reset_index().sort_values(['size'],ascending=[False])
headers=headers[headers['size']>10].Disease.unique()
network=pd.DataFrame(columns=headers)
for i in range(len(headers)):
temp_1=df[df.Disease == headers[i]]
ids=temp_1.Id.unique()
lista=[0]*len(headers)
for j in range(len(ids)):
temp_2=df[df.Id == ids[j]]
temp_2=temp_2[temp_2.Disease != headers[i]]
temp_lista=[]
for k in range(len(headers)):
temp_3=temp_2[temp_2.Disease == headers[k]]
temp_lista.append(len(temp_3))
lista=list(map(add,lista,temp_lista))
network.loc[i]=lista
network.insert(0,'Diseases',headers)
network.to_csv('table3.csv')
print ("My program took", time.time() - start_time, "to run")
Ваша помощь очень ценится!
1 ответ
1. Пример данных;
import pandas
df1 = pandas.DataFrame({
'Id' : [1, 2, 3],
'Diseases' : [['D1', 'D2', 'D3'], ['D2', 'D4', 'D5'], ['D1', 'D2', 'D5']],
'Age' : [90, 60, 70],
'Gender': ['Male', 'Female', 'Female']
})
df1
Выход:
Id Diseases Age Gender
0 1 [D1, D2, D3] 90 Male
1 2 [D2, D4, D5] 60 Female
2 3 [D1, D2, D5] 70 Female
2. Создайте таблицу 2;
df2 = (df1.join(df1['Diseases'].apply(pandas.Series))
.drop('Diseases', axis=1))
df2 = ( df2.set_index(['Id', 'Age', 'Gender'])
.stack().reset_index().drop('level_3', axis=1)
.rename(columns={0: 'Diseases'})
)
df2
Выход:
Id Age Gender Diseases
0 1 90 Male D1
1 1 90 Male D2
2 1 90 Male D3
3 2 60 Female D2
4 2 60 Female D4
5 2 60 Female D5
6 3 70 Female D1
7 3 70 Female D2
8 3 70 Female D5
3. Это то, что вы ищете?
Я действительно не понимаю, что вы здесь пытаетесь сделать.
df3.pivot_table(index=df3.Diseases, columns='Diseases', values='Id', aggfunc='count')
Ouput;
Diseases D1 D2 D3 D4 D5
Diseases
D1 2.0 NaN NaN NaN NaN
D2 NaN 3.0 NaN NaN NaN
D3 NaN NaN 1.0 NaN NaN
D4 NaN NaN NaN 1.0 NaN
D5 NaN NaN NaN NaN 2.0