【问题标题】:Find the value closest to median in a dataframe在数据框中找到最接近中位数的值
【发布时间】:2020-07-22 05:04:16
【问题描述】:

几个月前我刚刚接触了python,并且是这个论坛的新手。感谢是否有人可以提供帮助。 我想找到最接近中位数的值。

  1. 为了获得每个单元的中位数,我使用 groupby 和 median()。
  2. 然后获取与原始数据帧的差异
  3. 使用 abs() 和 idxmin() 获得最小的增量。 基本上我最终得到了另一个数据框,它的索引值最接近中位数。如何继续使用索引来获取实际值?
Unit    Test1   Test2   Test3
Unit1   0.254279388 0.010388754 0.820704593
Unit1   0.957139807 0.207681463 0.738428693
Unit1   0.043462803 0.154220478 0.606568744
Unit2   0.044308884 0.134817932 0.697317637
Unit2   0.244895686 0.909262442 0.153881824
Unit3   0.368147792 0.735655648 0.200679595
Unit3   0.30457518  0.929519313 0.823938759
Unit3   0.537633836 0.661168043 0.736937724
Unit3   0.410137495 0.567494043 0.68300754
Unit3   0.525483757 0.556830631 0.988314575

Unit    Test1   Test2   Test3
Unit1   0.254279388 0.154220478 0.738428693
Unit2   0.144602285 0.522040187 0.425599731
Unit3   0.410137495 0.661168043 0.736937724

这里是代码的sn-p。每列都应该有自己的索引,但 iloc 使用所有列的第一个索引

DATA_MEDIAN = DATA.groupby('Unit').median()

DATA_INDEX = (DATA.set_index(['Unit']) - DATA_MEDIAN).abs().reset_index().groupby('Unit').idxmin()

DATA_INDEX.reset_index(inplace=True)

DATA_CLOSEST = DATA.iloc[DATA_INDEX.index]

【问题讨论】:

  • 请告诉你你尝试了什么。给我们看一些代码。谢谢
  • 抱歉没有理解。我的意思是在您的问题中使用edit 并在那里显示您的代码。在问题正文中。
  • 哪一列的中位数?测试 1、测试 2 还是测试 3?
  • 是的,每个测试都有自己的单位中位数
  • 您正在寻找最接近中位数的值 - 但中位数究竟是什么?

标签: python


【解决方案1】:

这里有一个解决方案。请注意,对于只有两行的单位,选择最接近均值的值是任意的。

t = df.melt(id_vars="Unit")
t["distance_from_mean"] = t.groupby(["Unit", "variable"]).transform("mean").subtract(t.value, axis=0).abs()

t = t.loc[t.groupby(["Unit", "variable"], as_index=False)["distance_from_mean"].idxmin()]

res = pd.pivot_table(t, columns="variable", index = "Unit", values="value")
print(res)

输出是:

variable     Test1     Test2     Test3
Unit                                  
Unit1     0.254279  0.154220  0.738429
Unit2     0.044309  0.134818  0.153882
Unit3     0.410137  0.661168  0.683008

如果某些单元对于给定的测试只有 NaN 值,则需要稍微修改代码。见下文(以此类数据框为例):

df = pd.DataFrame({
    "Unit": ["Unit1"] * 3 + ["Unit2"] * 2 + ["Unit3"] * 5, 
    "Test1": range(10), 
    "Test2": range(10, 20), 
    "Test3": range(20,30)
})
df.loc[3:4, "Test2"] = np.NaN
print(df)

==>
    Unit  Test1  Test2  Test3
0  Unit1      0   10.0     20
...
3  Unit2      3    NaN     23
4  Unit2      4    NaN     24
5  Unit3      5   15.0     25
...

您要查找的代码:

t = df.melt(id_vars="Unit")
t["distance_from_mean"] = t.groupby(["Unit", "variable"]).transform("mean").subtract(t.value, axis=0).abs()

indices = t.groupby(["Unit", "variable"], as_index=False)["distance_from_mean"].idxmin()
indices.dropna(inplace = True)

t = t.loc[indices]

res = pd.pivot_table(t, columns="variable", index = "Unit", values="value")
print(res)

==>

variable  Test1  Test2  Test3
Unit                         
Unit1       1.0   11.0   21.0
Unit2       3.0    NaN   23.0
Unit3       7.0   17.0   27.0

【讨论】:

  • 您的代码仅适用于第一列(Test1),而其余的(Test2 和 Test3)遵循相同的索引。例如 Unit3,我需要找到最接近 5 个值中位数的值。对每一列(Test1/2/3)重复此操作,因此每一列的结果都不同。
  • 谢谢,它应该可以工作,但我收到 KeyError: 'Passing list-likes to .loc or [] with any missing labels'
  • 您使用的是哪个版本的熊猫?
  • 版本 1.0.5。我认为在第二个 groupby 之后删除了“distance_from_mean”列名。只需要把它放回去。
  • 我不这么认为。您是否使用与问题中完全相同的数据框?
猜你喜欢
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多