我有一个CSV,其数据具有多列中的数字值。我的目标是根据特定列中的下5个值是否在原始列的下方/上方,在其末尾添加-1、0或1的列。
例如,下面的数据,key: 0.0.0 value: x-y-z
key: 0.0.1 value: x-y-z
.
key: 0.0.59 value: x-y-z
.
key: 0.1.0 value x-y-z
key: 0.1.1 value x-y-z
key: 30.0.0 value: y-x-z
.
.
key: 30.0.59 value: y-x-z
.
key: 30.1.0 value: y-x-z
key: 30.1.1 value: y-x-z
key: 30.1.2 value: y-x-z
.
.
key: 30.1.59 value: y-x-z
key: 30.2.0 value: y-x-z
key: 30.2.1 value: y-x-z
key: 30-2.3 value: y-x-z
.
.
key: 60.0.0 value: z-y-x
key: 60.0.1 value: z-y-x
key: 60.0.2 value: z-y-x
.
.
key: 60.0.59 value: z-y-x
key: 60.1.0 value: z-y-x
key: 60.1.1 value: z-y-x
.
.
,如果开始>可以在同一列中结束,那么我可以执行一次操作,但是我该如何展望?我想要一个移动列,如果起始值是接下来5个结束值中的最低值,则放置1。如果起始位置是接下来5个结束值中的最高值,则放置-1。如果最终值在上下,则返回0。
np.where
答案 0 :(得分:1)
In [142]: txt = """0 5 1 // the start value here is the lowest of
...: the next 5 end values
...: 5 10 1 // same as above
...: 10 15 1 // same as above
...: 15 25 1 // same as above
...: 25 30 1 // same as above
...: 30 35 0 // end goes up and down so 0 here
...: 35 40 0 // same as above
...: 40 30 -1 // next are all below 40 so -1 now
...: 30 20
...: 20 15
...: 15 10
...: 10 5"""
In [143]: data = np.genfromtxt(txt.splitlines(), usecols=[0,1],encoding=None,
...: dtype=int)
In [144]: data
Out[144]:
array([[ 0, 5],
[ 5, 10],
[10, 15],
[15, 25],
[25, 30],
[30, 35],
[35, 40],
[40, 30],
[30, 20],
[20, 15],
[15, 10],
[10, 5]])
编写一个函数来处理一行(接下来的5行):
In [145]: def foo(data,i):
...: start = data[i,0]
...: ends = data[i:i+5,1]
...: if (start<ends).all():
...: return 1
...: if (start>ends).all():
...: return -1
...: else:
...: return 0
...:
测试特定的i
-令人惊讶的是,我第一次做对了!通常,对单词的描述进行解释很棘手,而且模棱两可。
In [146]: foo(data,0)
Out[146]: 1
In [147]: foo(data,5)
Out[147]: 0
In [148]: foo(data,7)
Out[148]: -1
现在只需迭代即可获得列表:
In [149]: [foo(data,i) for i in range(8)]
Out[149]: [1, 1, 1, 1, 0, 0, 0, -1]
填充此列表,以便可以将其附加到data
上,作为读者(或OP)的练习。
答案 1 :(得分:0)
如果您坚持使用numpy,则可以使用np.lib.stride_tricks.as_strided
来解决问题。如果我们将大小为5的额外维度添加到数组中,以便该维度上的跨度将您带到下一个元素,则可以沿该额外维度取最小值和最大值,然后将其与原始数组进行比较。
请记住,as_strided
是一门重载的大炮,它会在其他任何事情发生后立即将您射向您的脚:
start = np.array([0,5,10,15,25,30,35,40,30,20,15,10])
view = np.lib.stride_tricks.as_strided(start, shape=(start.size - 4, 5), strides=start.strides * 2, writeable=False)
move = ((start[:-4] == view.min(axis=1)).astype(int) - (start[:-4] == view.max(axis=1)))