如何获取数据框列中数字周围的值?

时间:2017-05-16 17:20:11

标签: python pandas dataframe

假设以下示例DataFrame:

df = pd.DataFrame([10,15,9,3,5,6,7,12,9], columns = ['numbers']).sort_values(by = 'numbers')


print df

   numbers
3       3
4       5
5       6
6       7
2       9
8       9
0      10
7      12
1      15

对于数字列中的每个值,我想要获取该值以及围绕它的 4 数字。这样,只要有可能,我想要比当前值小2个数字和2个数字。如果不可能,我想获取小于值的 k 数字和大于该值的 n 数字,例如k + n = 4

循环显示我的示例,第一个值是 3 。没有小于 3 的数字,因此输出为大于 3 的4个数字:
3 下,5,6,7,9

期望的输出: 输出列具有所需的输出,对应于数字列中的每个输入。 (我使用引号突出显示当前值)

   numbers  Output
3       3     '3' ,5,6,7,9
4       5     3, '5' ,6,7,9
5       6     3,5, '6' ,7,9
6       7     5,6, '7' ,9,9
2       9     6,7, '9' ,9,10
8       9           .
0      10           .
7      12           .
1      15     9,9,10,12, '15'

4 个答案:

答案 0 :(得分:1)

<强>设置

0 to N

<强>解决方案

N+1

答案 1 :(得分:0)

查看pd.rolling()pd.Series.shift()。然后只需将第一个和最后一个n作为一个特例:

df.loc[[0:4],['n1','n2','n3','n4']] = df['numbers'][:4].values

我建议将每个新值都设为一列,而不是将其全部打包到一个列中,因为它更容易使用这种方式。如果你愿意,你可以将它们连接到str。

答案 2 :(得分:0)

我无法想出一个聪明的人,但我觉得这很有效:

df2 =df.copy()
for i in range(-4, 5, 1):
    df2['{}_shifted'.format(str(i))] = df.numbers.shift(i)  #Here I'm making new columns to represent the shifted numbers

df2 =df2.drop('0_shifted', axis =1)  #dropping the 0_shifted column because it's the same as the `numbers` column

接下来我们要处理特殊情况,即前两行和后两行

nums = []
for i,j,in enumerate( df2.iterrows()):
     if np.isnan((j[1][-2])):
       nums.append(list(j[1])[i+1:i+5])

     elif np.isnan((j[1][2])):

        nums.append((list(j[1])[i-3:i+1]))


     else:

         nums.append(list(j[1])[len(list(j[1]))//2 -1:len(list(j[1]))//2 +3 ])

上面的代码将返回一个列表nums,我们将把它列入一个系列并连接到原始数据框

close_numbers =pd.Series(nums, index = df.index)


pd.concat((df, close_numbers), axis =1)

这也适用于一般情况。在某些情况下可能会中断,需要稍微调整一下。可能有更聪明的方法来提出更好的解决方案;无法找到一个聪明的方法。

让我知道它是否有效。

感谢。

答案 3 :(得分:0)

如果你想自己编写一个这样的学习经历,一个非常简单的方法是通过

def rollingWindow(x, size=2):
    n = len(x)
    results = []
    for i in range(n):
        temp = (x[i], x[:i][-size:], x[i:][1:(size+1)])
        results.append(temp)
        print(temp) ## only for show
    return results

如果您要传递一个简单的数字0到9的列表,那么

>>> rollingWindow(range(10))
(0, [], [1, 2])
(1, [0], [2, 3])
(2, [0, 1], [3, 4])
(3, [1, 2], [4, 5])
(4, [2, 3], [5, 6])
(5, [3, 4], [6, 7])
(6, [4, 5], [7, 8])
(7, [5, 6], [8, 9])
(8, [6, 7], [9])
(9, [7, 8], [])

正如您所看到的,对于第一行,只返回一个空列表,因为0之前没有任何内容。然后,对于下一行(1),返回[0],因为{{ 1}}位于0之前。

现在,如果您想将此应用到您的pandas数据框中,请将1添加到行的末尾以重置索引。

然后

reset_index(drop=True)

如输出所示,对于第一行值df = pd.DataFrame([10,15,9,3,5,6,7,12,9], columns = ['numbers']).sort_values(by = 'numbers').reset_index(drop=True) df.apply(rollingWindow, axis = 0) Out[5]: numbers 0 (3, [], [5, 6]) 1 (5, [3], [6, 7]) 2 (6, [3, 5], [7, 9]) 3 (7, [5, 6], [9, 9]) 4 (9, [6, 7], [9, 10]) 5 (9, [7, 9], [10, 12]) 6 (10, [9, 9], [12, 15]) 7 (12, [9, 10], [15]) 8 (15, [10, 12], []) ,没有过去的值,因此函数返回空列表,但也返回3,因为这些是未来值。然后,对于下一行[5,6],函数返回5作为过去值,[0]作为未来值。等等。

然后您可以修改它以适合您的目的。这只是一个例子,当然,绝不是最终&#34;最终&#34;。