在 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
如何解决此问题,以便获得第一次出现的“大差异”索引?
答案 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:
答案 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]