numpy 在拆分数组上查找给定搜索索引的段序号和内部索引

bd1hkmkf  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(87)

我有一个pandas框架,有1列:

df = pd.DataFrame({"Value": [10,9,5,11,2,8,6,7,4,2,1,9]})

字符串
如果我取其中的一个子集,起始索引值从0,1,2,3,4,5,6,7,8,9,10,11变为3,4,5,6,7:

df = df[3:8]


当我尝试使用.to_numpy()将其转换为numpy数组时,其索引将重置为0,1,2,3,4。但我需要将它们本身设置为3,4,5,6,7。

df_mod = df.to_numpy()


有没有人可以帮助创建这个numpy数组,它的索引与转换它的pandas数组的索引相同?

  • 编辑{进一步上下文}:*
  • 我有一个有2880个索引点的numpy数组,其中有一个特定的索引点- 1440,我需要一个标记。
  • 现在我需要把这个主数组分割成多个段--比如说100个段。我需要确定标记存在于这100个段中的哪个段中,以及标记存在于这个特定段的哪个索引点--比如说它在索引点60处。
  • 我会分裂成多个段的主数组比其他100以及所需的。因此,我需要一个模块化的代码,这将能够实现这一点的任何段号。我需要段号和标识段中的标记存在的索引。
  • 我原以为保留pandas df的索引会有助于实现这一点,但看起来numpy数组除了0之外不能有任何其他起始索引值,不像pandas数组。

这就是我目前正在做的创建细分:

# Convert pandas df to numpy array
signal = df['value'].values
# Split the signal into n no. of parts
num_parts = 100
segment_length = len(signal) // num_parts
segments = [signal[i:i + segment_length] for i in range(0, len(signal), segment_length)]


请提出如何做到这一点。

czq61nw1

czq61nw11#

pandas不同,NumPy数组不为行索引提供标签。
要保留初始df切片的索引,您可以执行以下操作之一:
arr = df[3:8].reset_index().values

array([[ 3, 11],
       [ 4,  2],
       [ 5,  8],
       [ 6,  6],
       [ 7,  7]])

字符串
从而第1和第2列将分别表示初始 * 索引/值 *,
或者通过DataFrame.to_records将切片转换为numpy记录数组(DataFrame标签作为字段):

arr = np.array(df[3:8].to_records().data)
array([(3, 11), (4,  2), (5,  8), (6,  6), (7,  7)],
      dtype=[('index', '<i8'), ('Value', '<i8')])

的数据
您可以通过字段名称访问,例如:

arr['index']
array([3, 4, 5, 6, 7])

更新:

从数学上讲,我们可以找到给定搜索索引的段序号和内部索引,甚至不需要实际拆分输入数组。
我将提供单独的定义,用于在N段上拆分数组,以及查找 * 段序号和给定搜索索引的内部索引 *:

# input array of 12 values
arr = pd.DataFrame({"value": [10, 9, 5, 11, 2, 8, 6, 7, 4, 2, 1, 9]}).values

def split_array(arr, seg_N):
    seg_size = arr.size // seg_N
    return np.split(arr, np.arange(1, seg_N) * seg_size)

def find_seg_by_idx(arr_size, seg_N, search_idx):
    """Find segment ordinal number and the inner position
       for a given search index
    """
    if search_idx >= arr_size:
        raise IndexError(f'{search_idx} is out of bounds')

    seg_size = arr_size // seg_N
    # segment ordinal number
    seg_num = min(search_idx // seg_size + 1, seg_N)
    # shift to the start of the segment to find the inner index
    inner_idx = search_idx - (seg_num * seg_size - seg_size)
    return seg_num, inner_idx


使用方法:

print(split_array(arr, 5))  # split 12-values arr on 5 segments/parts

[array([[10],
       [ 9]]), array([[ 5],
       [11]]), array([[2],
       [8]]), array([[6],
       [7]]), array([[4],
       [2],
       [1],
       [9]])]
print(find_seg_by_idx(10, seg_N=3, search_idx=7))

(3, 1)
print(find_seg_by_idx(12, seg_N=5, search_idx=11))

(5, 3)
cpjpxq1n

cpjpxq1n2#

提供更多的信息,如为什么你想这样做,将是有帮助的
FPandas会自动添加索引,但是当你使用to_numpy()时,它会变成一个没有任何索引的数组,因为数组本身是一种索引。

[[Array1],
[Array2] 
..
[ArrayN]]
Etc

字符串
如果你想有一个索引链接到数据点,你可以使用.to_dict(查看文档)

orient(str) {‘dict’, ‘list’, ‘series’, ‘split’, ‘tight’, ‘records’, ‘index’}


这将使索引和数据

{'3': ABC , '4': CDE,...,}


欢呼

oknrviil

oknrviil3#

一个numpy数组是位置索引的:一个像你这样的一维numpy数组总是从0len(arr)-1索引的。所以没有办法完全按照你想要的那样。
但是,如果你只需要使用这些索引来访问适当的值,你可以通过使用函数或字典将pandas索引转换为numpy索引来破解它:

>>> def idx_translate(df_idx):
...     return list(df[3:8].index).index(df_idx)
>>> idx_translate(3)
0
>>> df_mod[idx_translate(3)]
11

个字符
请注意,任何切片都需要自己的函数/字典。如果你需要更多的功能,你可以写一个类:

class IndexTranslator():
    def __init__(self, df):
        self.df = df
        self.idx_dict = {df_idx: idx
                         for idx, df_idx
                         in enumerate(df.index)}
    def idx(self, df_idx):
        return self.idx_dict[df_idx]


通过这种方式,您可以在任何时候创建一个新的切片时示例化类的一个新对象。

相关问题