Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Numpy:如何在多对值之间提取Numpy数组的行?_Python_Arrays_Pandas_Numpy_Structured Array - Fatal编程技术网

Python Numpy:如何在多对值之间提取Numpy数组的行?

Python Numpy:如何在多对值之间提取Numpy数组的行?,python,arrays,pandas,numpy,structured-array,Python,Arrays,Pandas,Numpy,Structured Array,我对Python比较陌生,目前在以有效的方式实现概念上简单的算法方面面临一些问题。 我已经能够在熊猫身上做到这一点(但执行起来相当慢) 我有一个由n行和3列组成的数据数组: -------------------- "A" | 1 | 12 -------------------- "B" | 2 | 34 -------------------- "S" | 3 | 1 -------------------- "B" | 4 | 145 ---

我对Python比较陌生,目前在以有效的方式实现概念上简单的算法方面面临一些问题。 我已经能够在熊猫身上做到这一点(但执行起来相当慢)

我有一个由n行和3列组成的数据数组:

--------------------
  "A"  |  1  |  12
--------------------
  "B"  |  2  |  34
--------------------
  "S"  |  3  |  1
--------------------
  "B"  |  4  |  145
--------------------
  "A"  |  5  |  132
--------------------
  "B"  |  6  |  234
--------------------
  "E"  |  7  |  1
--------------------
  "B"  |  8  |  15
--------------------
第一列表示id,第二列表示时间戳,第三列表示。 我必须只使用id“S”(开始)时间戳和id“E”(结束)时间戳之间包含时间戳的行来过滤ndarray。 在同一个数组中可能有多对“S”和“E”。对于非连续的“S”和“E”对,我需要最短的子阵列。换句话说,输出中不应出现id“S”或“E”

因此,输出应为:

--------------------
  "B"  |  4  |  145
--------------------
  "A"  |  5  |  132
--------------------
  "B"  |  6  |  234
--------------------
如前所述,我使用pandas获得了这个结果,但函数非常长且复杂,执行速度非常慢。因此,我确信使用numpy可以获得更好、最有效的算法

你有什么想法吗

提前谢谢

编辑

这里是一个代码片段,它使用pandas获得了预期的结果。 在“英特尔核心i7-6820@2.70GHz”处理器上,执行时间约为0.015秒

df = pd.DataFrame({'id': ['A', 'B', 'C', 'S', 'C', 'C', 'A', 'B', 'E', 'A', 'C', 'B', 'B', 'S', 'C', 'A', 'E', 'B'],
                   't': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],
                   'v': [145, 543, 12, 1, 14, 553, 65, 657, 1, 32, 54, 22, 11, 1, 6, 22, 1, 4]})
print(df)
res = pd.DataFrame()
id = "id"
t = "t"
v = "v"
id_bit_start = "S"
id_bit_end = "E"

# taking only "S" and "E" from df (when their value is 1)
df_data_bit = df.loc[
    ((df[id] == id_bit_start) |
     (df[id] == id_bit_end)) &
    (df[v] == 1.0)
    ]

# do something only if at least one "S" is present
if id_bit_start in df_data_bit[id].values:
    # creating empty list of time windows
    t_windows = list()
    t_wind_temp = [None, None]

    # for each bit "S" or "E"
    for index, bit in df_data_bit.iterrows():
        # if it is a "S"
        if bit[id] == id_bit_start:
            # set the start of the time window
            t_wind_temp[0] = bit[t]
        # if it is a "E" and the "S" has already been processed
        elif t_wind_temp[0] is not None:
            # set the end of the time window
            t_wind_temp[1] = bit[t]
            # append the current time window to our list
            t_windows.append(t_wind_temp)
            # reset the current time window
            t_wind_temp = [None, None]

    # taking everything but "S" and "E"
    df_data = df.loc[
        ~((df[id] == id_bit_start) |
          (df[id] == id_bit_end))
    ]

    # for each created time window
    for t_window in t_windows:
        # take only data with timestamps between the time window
        result = df_data.loc[
            (df_data[t] >= t_window[0])
            &
            (df_data[t] <= t_window[1])
            ]
        # append to the final result
        res = pd.concat([res, result])

print(res)
df=pd.DataFrame({'id':['A','B','C','S','C','A','B','E','A','C','B','B','S','C','A','E','B'],
‘t’:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],
v:[145543,12,1,14553,65657,1,32,54,22,11,1,6,22,1,4]})
打印(df)
res=pd.DataFrame()
id=“id”
t=“t”
v=“v”
id\u bit\u start=“S”
id_bit_end=“E”
#仅从df中获取“S”和“E”(当其值为1时)
df_数据_位=df.loc[
((df[id]==id\u位\u开始)|
(df[id]==id\u位\u结束))&
(df[v]==1.0)
]
#只有在至少有一个“S”的情况下才做某事
如果id_位从df_数据_位[id]开始。值:
#创建时间窗口的空列表
t_windows=list()
风温度=[无,无]
#对于每个位“S”或“E”
对于索引,df_data_bit.iterrows()中的位:
#如果是“S”
如果位[id]==id\u位\u开始:
#设置时间窗口的开始
t\u风温度[0]=位[t]
#如果是“E”且“S”已被处理
如果温度[0]不是无:
#设置时间窗口的结尾
t_风_温度[1]=位[t]
#将当前时间窗口附加到列表中
t_windows.append(t_wind_temp)
#重置当前时间窗口
风温度=[无,无]
#除了“S”和“E”以外的所有东西
df_数据=df.loc[
~((df[id]==id\u位\u开始)|
(df[id]==id\u位\u结束))
]
#对于每个创建的时间窗口
对于t_窗口中的t_窗口:
#仅获取时间窗口之间带有时间戳的数据
结果=df_data.loc[
(df_数据[t]>=t_窗口[0])
&

(df_数据[t]这会考虑S和E连续性的不确定性:
假设您的时间戳按升序排列:

import re

a = df.to_records(index=False)
idx = [m.span() for m in re.finditer('S[^{SE}]*?E', ''.join(a['id']))]
indexer = np.r_[tuple([np.s_[i+1:j-1] for (i,j) in idx])]
a_filtered = a[indexer]
说明

快速计算此值有一些技巧:

  • 将数据帧转换为结构化阵列
  • 将所有id字符转换为字符串
  • 查找
    S.*E
    的非贪婪匹配(注意,如果您的id不是单个字母,则可以将S和E更改为任何子字符串)
  • 获取找到的子字符串的开始和结束的索引
  • 在4中的这些索引之间创建所有索引的列表
  • 使用5中的索引筛选数组

  • 这将考虑S和E连续性的不确定性:
    假设您的时间戳按升序排列:

    import re
    
    a = df.to_records(index=False)
    idx = [m.span() for m in re.finditer('S[^{SE}]*?E', ''.join(a['id']))]
    indexer = np.r_[tuple([np.s_[i+1:j-1] for (i,j) in idx])]
    a_filtered = a[indexer]
    
    说明

    快速计算此值有一些技巧:

  • 将数据帧转换为结构化阵列
  • 将所有id字符转换为字符串
  • 查找
    S.*E
    的非贪婪匹配(注意,如果您的id不是单个字母,则可以将S和E更改为任何子字符串)
  • 获取找到的子字符串的开始和结束的索引
  • 在4中的这些索引之间创建所有索引的列表
  • 使用5中的索引筛选数组

  • 你介意分享一个代码来生成numpy,或者也许是你在熊猫身上所做的事情,因为熊猫在最新操作方面非常好欢迎来到StackOverflow。请花时间阅读这篇文章,以及如何提供一个新的答案,并相应地修改你的问题。这些关于如何提出一个好问题的提示可能也很有用。谢谢关于你的提示,我已经更新了我的qustion@Luigi你想让S和E对成为连续的对吗?@Ehsan我确信数据是按升序时间戳排序的,但我不知道S和E是否总是连续的,有时可能会出现我有S,然后缺少一个E,然后是另一个S和E(这就是为什么在代码的“iterrows()”部分有一些检查)你介意分享一个代码来生成numpy,或者也许是你在熊猫身上所做的事情,因为熊猫在最新操作方面非常好欢迎来到StackOverflow。请花时间阅读这篇文章,以及如何提供一个新的答案,并相应地修改你的问题。这些关于如何提出一个好问题的提示可能也很有用。谢谢关于你的提示,我已经更新了我的qustion@Luigi你想让S和E对成为连续的对吗?@Ehsan我确信数据是按升序时间戳排序的,但我不知道S和E是否总是连续的,有时可能会出现我有S,然后缺少一个E,然后是另一个S和E(这就是为什么代码的“iterrows()”部分有一些检查)感谢您澄清问题。我刚刚看到更新。将相应地更新答案。是的,时间戳可能有间隙,但始终按顺序排列