首页 > 解决方案 > 通过使用 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 和一个 isoforms。我想折叠“case_id”并为 mirnas 和 isoforms 文件名创建新列。我正在努力实现这一目标:

  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 来填充这些列。但我不太确定该怎么做。

有人可以帮忙吗?

标签: pythonreshape

解决方案


您可以通过将它们分成不同的数据框,然后将它们连接在一起来做到这一点:

我还注意到有些值被称为“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 使用起来非常不直观,所以不要因为不总是使用它而感到难过(即使它可能更有效,就像这里一样)


推荐阅读