pandas 如何在多级索引中将字符串值排序为数字值?

b91juud3  于 2023-05-15  发布在  其他
关注(0)|答案(1)|浏览(169)

因此,我一直在尝试按其检测编号和样本ID对数据集进行排序,取每个检测编号的所有样本重复的平均值(例如:在一个测定编号中运行的样品可能已运行1-10次)。
这样做,我在pandas中使用了groupby方法,并且成功地使用了9以上的示例名称(例如,10、11、20、50)将被排序在较低的样本编号附近(例如,10在1下,20在2下,50在5下),而不是它们应该在列中的位置。
我知道这是sorted_values方法从左到右检查的问题,但现在我甚至不能使用natsorted方法来纠正它,而不完全取消groupby。
我已经尝试过在进行groupby之前按照我想要的方式对数据进行排序,但这并不起作用,因为它在之后再次排序。我还尝试了sort = False,但检测编号在错误的位置,我再次无法正确排序。

import pandas as pd
import numpy as np
import natsort as ns

#Takes a sheet from an excel file and turns it into a data frame. 

excel_name = "~~~~"
from_sheet_name = "OARS 2-8 "
output_name = "~~~ Data2.xlsx"

df = pd.read_excel(excel_name, from_sheet_name)
df.head(5)

#Prepares the averaged ALUs
df2= df.groupby(["Assay Num", "Sample Name"],sort = True)
average_alus = df2["Resp 1"].agg(np.mean)
# # average_alus["Sample Name"] = ns.natsorted(average_alus["Sample 
Name"])
# # ns.natsorted(average_alus["Sample Name"])
# average_alus_df = pd.DataFrame(average_alus)
# type(average_alus_df)
# average_alus_df = average_alus_df.reset_index()
# average_alus_df["Sample Name"] = 
ns.natsorted(average_alus_df["Sample Name"])
# average_alus_df

# Prepares the data for the second sheet. Takes assay number, sample 
name, and ALUs, sorts them, and drops empty rows

df3 = df[["Assay Num","Sample Name", "Resp 1"]]
df3 = df3.sort_values(["Assay Num", "Sample Name"], ascending = 
[True, True])
# df3["Sample Name"] = ns.natsorted(df3["Sample Name"])
df3 = df3.dropna()

# Writes both sheets to an excel file
writer2 = pd.ExcelWriter(output_name)
average_alus.to_excel(writer2, sheet_name = "Averaged ALUs", index = 
"False")
df3.to_excel(writer2, sheet_name = "Raw Reps Sorted", index = 
"False")

writer2.save()

这是我的第一次尝试,第二次尝试被注解掉了。这就是我想要的table的样子
| 试验编号|样品名称|ALU|
| --------------|--------------|--------------|
| 一百七十五|CRM 1|一千五百零七|
| | CRM 2| 2.8|
| | ~~~|~|
| | CRM 10|三百|
与它实际上的样子
| 试验编号|样品名称|ALU|
| --------------|--------------|--------------|
| 一百七十五|CRM 1|一千五百零七|
| | CRM 10|三百|
| | CRM 2| 2.8|
| | CRM 3|九点七|
一旦我尝试在将series转换回dataframe后对其进行排序,groupby就会被撤消
| 试验编号|样品名称|ALU|
| --------------|--------------|--------------|
| 一百七十五|CRM 1|一点四零七|
| 一百七十五|CRM 1|一点五|
| 一百七十五|CRM 1| 1.3|
| 一百七十五|CRM 2|九点七|

dw1jzc5e

dw1jzc5e1#

下面是一个模仿你的玩具数据框:

import random

import pandas as pd

df = pd.DataFrame(
    {
        "Assay num": [176] * 10 + [175] * 10,
        "Sample Name": random.sample([f"CRM {i+1}" for i in range(10)], k=10) * 2,
        "ALUs": [random.randint(1, 2_000) for _ in range(10)] * 2,
    }
)
print(df)
# Output

    Assay num Sample Name  ALUs
0         176       CRM 3  1392
1         176       CRM 2   869
2         176       CRM 4  1732
3         176       CRM 1  1385
4         176       CRM 5    49
5         176       CRM 8  1898
6         176       CRM 6  1965
7         176      CRM 10   626
8         176       CRM 7   845
9         176       CRM 9  1191
10        175       CRM 3  1392
11        175       CRM 2   869
12        175       CRM 4  1732
13        175       CRM 1  1385
14        175       CRM 5    49
15        175       CRM 8  1898
16        175       CRM 6  1965
17        175      CRM 10   626
18        175       CRM 7   845
19        175       CRM 9  1191

下面是一种将字符串值作为数值进行排序的方法,最终成为多级索引:

new_df = pd.concat(
    [
        sub_df.sort_values("Sample Name", key=lambda col: col.str[4:].astype(int))
        .groupby(["Assay num", "Sample Name"], sort=False)
        .agg(sum)  # will not sum anything
        for _, sub_df in df.groupby(["Assay num"])
    ]
)
print(new_df)
# Output

Assay num Sample Name      
175       CRM 1        1385
          CRM 2         869
          CRM 3        1392
          CRM 4        1732
          CRM 5          49
          CRM 6        1965
          CRM 7         845
          CRM 8        1898
          CRM 9        1191
          CRM 10        626
176       CRM 1        1385
          CRM 2         869
          CRM 3        1392
          CRM 4        1732
          CRM 5          49
          CRM 6        1965
          CRM 7         845
          CRM 8        1898
          CRM 9        1191
          CRM 10        626

相关问题