如何找到熊猫数据框的值的首次显着差异?

时间:2020-07-20 05:54:58

标签: python pandas numpy dataframe

Pandas DataFrame 中,我如何找到两个相邻索引处的两个值之间第一次出现较大差异?

例如,如果我有一个包含数据[1, 1.1, 1.2, 1.3, 1.4, 1.5, 7, 7.1, 7.2, 15, 15.1] DataFrame A ,我希望索引保持1.5,即5。下面的代码,它将使我的索引保持为7.2,因为15 - 7.2 > 7 - 1.5

idx = df['A'].diff().idxmax() - 1

如何解决此问题,以便获得第一次出现的“大差异”索引?

4 个答案:

答案 0 :(得分:1)

一个想法是通过Series.quantile过滤一系列差值,并用-1和差值的变化顺序排列差值,最后得到第一个索引:

df = pd.DataFrame({'A':[1, 1.1, 1.2, 1.3, 1.4, 1.5, 7, 7.1, 7.2, 15, 15.1]})


x = df['A'].diff(-1) .abs()
print (x)
0     0.1
1     0.1
2     0.1
3     0.1
4     0.1
5     5.5
6     0.1
7     0.1
8     7.8
9     0.1
10    NaN
Name: A, dtype: float64

idx = x.index[x >= x.quantile(.75)]
print (idx)
Int64Index([5, 7, 8], dtype='int64')

print (idx[0])
5

答案 1 :(得分:0)

如果您有一个Numpy数组,可以将其用作任何数据框行,则可以使用numpy.argmax

import numpy as np

import numpy as np

a = np.array([1, 1.1, 1.2, 1.3, 1.4, 1.5, 7, 7.1, 7.2, 15, 15.1])
diff = np.diff(a)
threshold = 2 # set your threshold
max_index = np.argwhere(diff> threshold) [[5],[8]]

参考: https://numpy.org/doc/stable/reference/generated/numpy.diff.html https://numpy.org/doc/stable/reference/generated/numpy.argwhere.html

更多信息:

pandas.diff将计算差异diff[i] = a[i] - a[i-1]
numpy.diff将计算差异diff[i] = a[i+1] - a[i]
除了i = max len:

  • a [i] = a [i] -a [i-1]

答案 2 :(得分:0)

当然,主要问题是如何定义“大差异”。您的解决方案非常有用,可以最大程度地提高差异,仅通过使用jump()并使用Jezrael所示的绝对值来改进:

Animal

如果您的值未排序,则使用绝对值很重要,在这种情况下,您会得到负差。

然后,您可能应该对这些值进行一些聚类,并获得具有最大值的聚类的最小索引。杰斯雷尔(Jezrael)已经通过使用最大的四分位数显示了一种启发式方法,但是仅通过稍微修改您的示例就无法实现:

.diff(-1)

这将返回differences = df['A'].diff(-1).abs()

以下三种可能更适合您的启发式方法:

  • 如果您拥有一个大于该值的值,则认为差异是“大的”(例如df = pd.DataFrame({'A': [1, 1.05, 1.2, 1.3, 1.4, 1.5, 7, 7.1, 7.2, 15, 15.1]}) differences = df['A'].diff(-1).abs() idx = differences.index[differences >= differences.quantile(.75)][0] print(idx, differences[idx]) ):

    1 0.1499999999999999
  • 如果知道有多少个大值,则可以选择这些值并获得最小的索引(例如1.5):

    idx = differences.index[differences >= 1.5][0]
    
  • 如果您知道所有较小的值都组合在一起(例如示例中的所有0.1),则可以过滤大于平均值的值(如果“较大”值非常大,则可以过滤平均值+ 1标准偏差)接近较小的)。

    2

    这是因为与中位数相反,您的几个大差异将使平均值显着上升。

如果您真的想进行适当的聚类,则可以使用scikit learning中的KMeans算法:

idx = differences.nlargest(2).index.min()

这将数据分为2类,然后将其分类为pandas系列。然后,我们仅选择具有最高值的簇来过滤该系列的索引,最后获得此过滤索引的第一个元素。

答案 3 :(得分:0)

""" SqlAlchemy ClickHouse database session maker """

db = Database('test', db_url=os.environ['TEST_CONNECTION'],
              username=os.environ['CLICKHOUSE_USER'], password=os.environ['CLICKHOUSE_PASSWORD'])
db.create_database()
db.create_table(OHLC)

def shift(a):
  
  a_r = np.roll(a, 1) # right shift
  a_l = np.roll(a, -1) # left shift


  return np.stack([a_l, a_r], axis=1)

a = np.array([1, 1.1, 1.2, 1.3, 1.4, 1.5, 7, 7.1, 7.2, 15, 15.1])

diff = abs(shift(a) - a.reshape(-1, 1))

diff = diff[1:-1]

indices = diff.argmax(axis=0) - 2

a[indices]