#python #reshape
#python #изменение формы
Вопрос:
У меня есть фрейм данных, который выглядит следующим образом:
data = {'case_id': ['aaa', 'aaa', 'bbb', 'ccc', 'bbb', 'ccc'],
'file_name': ['512.mirnas', '512.isoforms', '360.isoforms', '478.mirnas', '360.mirnas', '478.isoforms']
}
df = pd.DataFrame(data, columns=['case_id', 'file_name'])
case_id file_name
0 aaa 512.mirnas
1 aaa 512.isoforms
2 bbb 360.isoforms
3 ccc 478.mirnas
4 bbb 360.mirnas
5 ccc 478.isoforms
Для каждого уникального «case_id» есть два «file_names», одна mirnas и одна изоформа. Я хочу свернуть «case_id» и создать новые столбцы для имени файла mirnas и изоформ. Я пытаюсь добиться этого:
case_id file_name_mirnas file_name_isoforms
0 aaa 512.mirnas 512.isoforms
1 bbb 360.mirnas 360.isoforms
2 ccc 478.mirnas 478.isoforms
Я совсем новичок в Python, и мне трудно это сделать. Я попробовал в df.pivot, но это не сработало. Я получил следующую ошибку:
ValueError: Index contains duplicate entries, cannot reshape
Я подумал, может быть, я мог бы создать два новых пустых столбца «file_name_mirnas» и «file_name_isoforms», а затем использовать groupby для заполнения этих столбцов. Но я не очень уверен, как это сделать.
Может кто-нибудь, пожалуйста, помочь?
Ответ №1:
Вы можете сделать это, разделив их на разные фреймы данных, а затем объединив их вместе:
Я также заметил, что некоторые значения называются «mirna» вместо «mirnas». Я изменил это для своего ответа.
import pandas as pd
data = {'case_id': ['aaa', 'aaa', 'bbb', 'ccc', 'bbb', 'ccc'],
'file_name': ['512.mirnas', '512.isoforms', '360.isoforms', '478.mirnas', '360.mirnas', '478.isoforms']
}
df = pd.DataFrame(data, columns=['case_id', 'file_name'])
df_mirnas = df[df["file_name"].str.endswith("mirnas")] # Grabs all that end with mirnas
df_mirnas.rename(columns={"file_name": "file_name_mirnas"}, inplace=True) # Rename for join
df_iso = df[df["file_name"].str.endswith("isoforms")] # Grabs all that ends with isoforms
df_iso.rename(columns={"file_name": "file_name_isoforms"}, inplace=True) # rename for join
df_new = df_mirnas.join(df_iso.set_index("case_id"), on="case_id") # Joins them on case_id
df_new
>>
case_id file_name_mirnas file_name_isoforms
0 aaa 512.mirnas 512.isoforms
3 ccc 478.mirnas 478.isoforms
4 bbb 360.mirnas 360.isoforms
PS, я думаю, что groupby очень неинтуитивен в использовании, поэтому не расстраивайтесь из-за того, что вы не всегда его используете (даже если он, вероятно, более эффективен, как здесь)
Ответ №2:
Если вы не знаете запросы в pandas, вы можете сделать это таким образом. 1- разделите строки 2- выберите два имени файлов для каждого случая 3- создание нового фрейма данных
from numpy.lib.arraysetops import unique
import pandas as pd
data = {'case_id': ['aaa', 'aaa', 'bbb', 'ccc', 'bbb', 'ccc'],
'file_name': ['512.mirnas', '512.isoforms', '360.isoforms', '478.mirnas', '360.mirnas', '478.isoforms']
}
df = pd.DataFrame(data, columns=['case_id', 'file_name'])
print(df)
unique_caseid = sorted(set(df.loc[:, 'case_id']))
mirnas = []
isoforms = []
for id in unique_caseid:
# first file name
temp_index = list(df.loc[:, 'case_id']).index(id)
file_name = df.loc[temp_index, 'file_name']
if 'mirnas' in file_name:
mirnas.append(file_name)
else:
isoforms.append(file_name)
# 2nd file name
ntemp_index = list(df.loc[:, 'case_id'])[temp_index 1:].index(id)
temp_index = ntemp_index 1
file_name = df.loc[temp_index, 'file_name']
if 'mirnas' in file_name:
mirnas.append(file_name)
else:
isoforms.append(file_name)
data = {}
data['case_id'] = unique_caseid
data['file_name_mirnas'] = mirnas
data['file_name_iosforms'] = isoforms
newdf = pd.DataFrame(
data, columns=['case_id', 'file_name_mirnas', 'file_name_iosforms'])
print(newdf)
Ответ №3:
Вы можете создать временный столбец для хранения mirnas
, а isoforms
затем использовать функцию pivot для изменения формы ваших данных, прежде чем окончательно свернуть столбцы с пониманием списка:
df = (df.assign(temp=df.file_name.str.split(".").str[-1])
.pivot("case_id", "temp")
)
# flatten columns
df.columns = ["_".join(entry) for entry in df]
df.reset_index()
case_id file_name_isoforms file_name_mirnas
0 aaa 512.isoforms 512.mirnas
1 bbb 360.isoforms 360.mirnas
2 ccc 478.isoforms 478.mirnas