【问题标题】:Index returned by np.argmax of a series within a dataframe slice points to wrong value when used as index into same dataframe当用作同一数据帧的索引时,数据帧切片内的系列的 np.argmax 返回的索引指向错误的值
【发布时间】:2021-04-20 18:24:24
【问题描述】:

我有一个从收集的采样数据创建的数据框。然后我操作数据框以删除重复项、排序和删除饱和值:

df = pd.read_csv(path+ newfilename, header=0, usecols=[0,1,2,3,5,7,10],
                names=['ch1_real', 'ch1_imag', 'ch2_real', 'ch2_imag', 'ch1_log_mag', 'ch1_phase',
                      'ch2_log_mag', 'ch2_phase', 'pr_sample_real', 'pr_sample_imag', 'distance'])    
tmp=df.drop_duplicates(subset='distance', keep='first').copy()
tmp.sort_values("distance", inplace=True)
dfUnique=tmp[tmp.distance <65000].copy()

我还添加了两个计算值(在@Stef 的帮助下) dfUnique['ch1_log_mag']=20np.log10((dfUnique.ch1_real +1jdfUnique.ch1_imag).abs()) dfUnique['ch2_log_mag']=20np.log10((dfUnique.ch2_real +1jdfUnique.ch2_imag).abs())

当我试图找到最大幅度的索引时,问题就出现了。事实证明(对我来说出乎意料),数据框保留了原始数据索引。因此,在排序和删除行之后,给定行的索引不是它在新有序数据帧中的索引,而是它在原始数据帧中的行索引:

         ch1_real  ch1_imag  ch2_real  ...  distance  ch1_log_mag  ch2_log_mag
79   0.011960 -0.003418  0.005127  ...       0.0   -38.104414   -33.896518
78  -0.009766 -0.005371 -0.015870  ...       1.0   -39.058001   -34.533870
343  0.002197  0.010990  0.003662  ...       2.0   -39.009865   -37.278737
80  -0.002686  0.010740  0.011960  ...       3.0   -39.116435   -34.902513
341 -0.007080  0.009033  0.016600  ...       4.0   -38.803434   -35.582833
81  -0.004883 -0.008545 -0.016850  ...      12.0   -40.138523   -35.410047
83  -0.009277  0.004883 -0.000977  ...      14.0   -39.589769   -34.848170
84   0.006592 -0.010250 -0.009521  ...      27.0   -38.282239   -33.891250
85   0.004395  0.010010  0.017580  ...      41.0   -39.225735   -34.890353
86  -0.007812 -0.005127 -0.015380  ...      53.0   -40.589187   -35.625615

然后当我使用:

np.argmax(dfUnique.ch1_log_mag)

要找到最大幅度的索引,这将返回 有序数据帧系列中的索引。但是,当我使用它来索引数据框以提取该行中的其他值时,我会从该行索引处的原始数据框中获取元素。

我将数据框导出到 Excel,以便更轻松地观察正在发生的事情。第 1 列是数据帧索引。请注意,它与电子表格上的行号不同。

上面的 np.argmax 命令返回 161。如果我查看新的有序数据框,索引 161 是下面突出显示的这一行(数据从电子表格中的第二行开始,而索引在 python 中从 0 开始): 并且是正确的。但是,根据原始数据帧顺序,这是在索引 238 处。当我尝试访问 ch1_log_max[161] 时,

dfUnique.ch1_log_mag[161]

我得到 -30.9759,而不是 -11.453。它使用 161 作为原始数据帧的索引来获取值:

这很可怕——两个函数使用两个不同的参考框架(至少对于 Python 新手而言)。我该如何避免这种情况? (如何)我要重新索引数据框吗?还是我应该使用等效的 pandas 方法在数据框中找到系列中的最大值(假设问题是由于 pandas 和 numpy 如何对数据进行操作)?问题是我创建数据框副本的方式吗?

【问题讨论】:

  • np.argmax 是一个numpy 函数。如果给定 pandas 系列,它将与该系列中的 values 数组一起使用。这是一个相对位置。它不关注pandas 定义的系列索引。在pandas 中查找确实使用索引的等效项。

标签: python dataframe numpy indexing max


【解决方案1】:

如果您对数据框进行排序,它会保留索引。

import pandas as pd
a = pd.DataFrame(np.random.randn(24).reshape(6,4), columns=list('abcd'))
a.sort_values(by='d', inplace=True)
print(a)
>>>
          a         b         c         d
2 -0.553612  1.407712 -0.454262 -1.822359
0 -1.046893  0.656053  1.036462 -0.994408
5 -0.772923 -0.554434 -0.254187 -0.948573
4 -1.660773  0.291029  1.785757 -0.457495
3  0.128831  1.399746  0.083545 -0.101106
1 -0.250536 -0.045355  0.072153  1.871799

要重置索引,可以使用.reset_index(drop=True)

b = a.sort_values(by='d').reset_index(drop=True)
print(b)
>>>
          a         b         c         d
0 -0.553612  1.407712 -0.454262 -1.822359
1 -1.046893  0.656053  1.036462 -0.994408
2 -0.772923 -0.554434 -0.254187 -0.948573
3 -1.660773  0.291029  1.785757 -0.457495
4  0.128831  1.399746  0.083545 -0.101106
5 -0.250536 -0.045355  0.072153  1.871799

要找到最大值的原始索引,可以使用.idxmax()然后使用.loc[]

ix_max = a.d.idxmax()
# or ix_max = np.argmax(a.d)
print(f"ix_max = {ix_max}")
a.loc[ix_max]
>>>
ix_max = 1
a   -0.250536
b   -0.045355
c    0.072153
d    1.871799
Name: 1, dtype: float64

或者如果你有新的索引订单,你可以使用.iloc:

iix = np.argmax(a.d.values)
print(f"iix = {iix}")
print(a.iloc[iix])
>>>
iix = 5
a   -0.250536
b   -0.045355
c    0.072153
d    1.871799
Name: 1, dtype: float64

你可以看看https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html

【讨论】:

  • 谢谢!正是我想要的,包括 pandas 用户指南。
猜你喜欢
  • 2020-01-24
  • 2015-01-02
  • 2021-11-09
  • 1970-01-01
  • 2022-11-03
  • 1970-01-01
  • 2019-08-12
  • 2021-10-29
  • 2019-07-22
相关资源
最近更新 更多