使用re.compile().split()循环数据帧的行

2024-05-28 20:54:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧taht由1列和几行组成。这些行中的每一行都以相同的方式构造:-时间戳-值1值2值3-时间戳-值4值5值6

时间戳的格式为:YYYY-MM-DD HH:MM:SS,值为带2位小数的数字。 我想创建一个新的数据帧,它在一行中有单独的时间戳,在下一行中有相关的值

我用正则表达式设法获得了行级的预期结果,但没有得到整个数据帧的预期结果

到目前为止,我的代码是:

#input dataframe
data.head()

                  values
0   2020-05-12 10:00:00 12.07 13 11.56 ... 2020-05-12 10:00:01 11.49 17 5.67...
1   2020-05-12 10:01:00 11.49 17 5.67 ... 2020-05-12 10:01:01 12.07 13 11.56...
2   2020-05-12 10:02:00 14.29 18 11.28 ... 2020-05-12 10:02:01 13.77 18 7.43...


test = data['values'].iloc[0] #first row of data
row1 = re.compile("(\d\d\d\d\S\d\d\S\d\d\s\d\d\S\d\d\S\d\d)").split(test)
df_row1 = pd.DataFrame(row1)

df_row1.head()

             values 
0   2020-05-12 10:00:00
1   12.07 13.79 15.45 17.17 18.91 14.91 12.35 14....
2   2020-05-12 10:00:01
3   12.48 13.96 13.88 15.57 18.46 15.0 13.65 14.6...

#trying the same for the entire dataframe 
for row in data:
    df_new = re.compile("(\d\d\d\d\S\d\d\S\d\d\s\d\d\S\d\d\S\d\d)").split(row)

print(df_new)
['values']

我现在的问题是如何循环遍历数据帧的行并获得预期的结果


Tags: the数据testredataframedfdata时间
2条回答

您不需要通过行循环来获得结果,相反,您可以使用^{}围绕分隔符分割给定的序列,在本例中,分隔符将是一个正则表达式。然后,您可以使用^{}来转换列表中的每个元素,例如分隔行

使用:

data["values"] = data["values"].str.split(r'\s+(?=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})')
data = data.explode("values")
data["values"] = data["values"].str.split(r'(?<=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s+')
data = data.explode("values").reset_index(drop=True)

print(data)

由此产生的数据帧data应该如下所示:

        values
0   2020-05-12 10:00:00
1        12.07 13 11.56
2   2020-05-12 10:00:01
3         11.49 17 5.67
4   2020-05-12 10:01:00
5         11.49 17 5.67
6   2020-05-12 10:01:01
7        12.07 13 11.56
8   2020-05-12 10:02:00
9        14.29 18 11.28
10  2020-05-12 10:02:01
11        13.77 18 7.43

如果要首先拆分行并将值提取到列中,请注意可以使用str.extract。在正则表达式中使用命名分组,它将自动为数据帧分配列

split_line = r"\s+(?=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})"
extract_values = r"(?P<date>\d{4}-\d{2}-\d{2})\s(?P<time>\d{2}:\d{2}:\d{2})\s(?P<value_one>.*?)\s(?P<value_two>.*?)\s(?P<value_three>.*?)$"

df = pd.DataFrame([{
    "value": "2020-05-12 10:00:00 12.07 13 11.56 2020-06-12 11:00:00 13.07 16 11.16 2020-05-12 10:00:01 11.49 17 5.67", 
},{
    "value": "2020-05-13 10:00:00 14.07 13 15.56 2020-05-16 10:00:02 11.51 18 5.69", 
}])
df = df["value"].str.split(split_line).explode().str.extract(extract_values, expand=True)
print(df)
#          date      time value_one value_two value_three
# 0  2020-05-12  10:00:00     12.07        13       11.56
# 0  2020-06-12  11:00:00     13.07        16       11.16
# 0  2020-05-12  10:00:01     11.49        17        5.67
# 1  2020-05-13  10:00:00     14.07        13       15.56
# 1  2020-05-16  10:00:02     11.51        18        5.69

如果您不知道日期和时间之后的组数,请使用split而不是正则表达式。我建议这样做:

split_line = r"\s+(?=\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})"

df = pd.DataFrame([{
    "value": "2020-05-12 10:00:00 12.07 13 11.56 2020-06-12 11:00:00 13.07 16 11.16 2020-05-12 10:00:01 11.49 17 5.67", 
},{
    "value": "2020-05-13 10:00:00 14.07 13 14 15 15.56 2020-05-16 10:00:02 11.51 18 5.69", 
}])
df = df["value"].str.split(split_line).explode().reset_index()

df = df['value'].str.split(" ").apply(pd.Series)
df.columns = [f"col_{col}" for col in df.columns]
print(df)
#         col_0     col_1  col_2 col_3  col_4 col_5  col_6
# 0  2020-05-12  10:00:00  12.07    13  11.56   NaN    NaN
# 1  2020-06-12  11:00:00  13.07    16  11.16   NaN    NaN
# 2  2020-05-12  10:00:01  11.49    17   5.67   NaN    NaN
# 3  2020-05-13  10:00:00  14.07    13     14    15  15.56
# 4  2020-05-16  10:00:02  11.51    18   5.69   NaN    NaN

相关问题 更多 >

    热门问题