我正在构建一个系统,其中raspberry pi通过蓝牙接收数据并将其解析为pandas数据帧以进行进一步处理。但是,有一些问题。蓝牙数据包被转换为pandas Series对象,我尝试将其成功附加到空数据框中。执行以下拆分操作是为了从蓝牙数据包中提取遥测信息。
代码用正确的列名创建了一个合适的数据框,但是当我追加到它之后,Series对象的行号变成了新的列。每个附加的系列在最终数据框中都是一行。我想知道的是:如何将Series对象添加到数据框中,以便将值放入索引从0到6而不是7到14的列中?
编辑:添加了一个screenshot, 输出在顶部,在下面是pkt的倍数。
Edit2:添加了每个请求的完整代码。添加了错误回溯。
import time
import sys
import subprocess
import pandas as pd
import numpy as np
class Scan:
def __init__(self, count, columns):
self.running = True
self.count = count
self.columns = columns
def run(self):
i_count = 0
p_data = pd.DataFrame(columns=self.columns, dtype='str')
while self.running:
output = subprocess.check_output(["commands", "to", "follow.py"]).decode('utf-8')
p_rows = output.split(";")
series_list = []
print(len(self.columns))
for packet in p_rows:
pkt = pd.Series(packet.split(","),dtype='str', index=self.columns)
pkt = pkt.replace('\n','',regex=True)
print(len(pkt))
series_list.append(pkt)
p_data = pd.DataFrame(pd.concat(series_list, axis=1)).T
print(p_data.head())
print(p_rows[0])
print(list(p_data.columns.values))
if i_count == self.count:
self.running = False
sys.exit()
else:
i_count += 1
time.sleep(10)
def main():
columns = ['mac', 'rssi', 'voltage', 'temperature', 'ad count', 't since boot', 'other']
scan = Scan(0, columns)
while True:
scan.run()
if __name__ == '__main__':
main()
回溯(最近通话最近): 在第48行的文件“ blescanner.py”中 主要() 主文件“ blescanner.py”,第45行 scan.run()
文件“ blescanner.py”,第24行,正在运行 pkt = pd.Series(packet.split(“,”),dtype ='str',index = self.columns)
在 init 中的文件“ /mypythonpath/site-packages/pandas/core/series.py”,第262行 .format(val = len(data),ind = len(index)))
ValueError:传递的值的长度为1,索引暗含7
答案 0 :(得分:1)
您不想以这种方式附加到DataFrame。您可以做的是创建一系列列表,并将它们串联在一起。
所以,像这样:
series_list = []
for packet in p_rows:
pkt = pd.Series(packet.split(","),dtype='str')
print(pkt)
series_list.append(pkt)
p_data = pd.DataFrame(pd.concat(series_list), columns=self.columns, dtype='str')
只要您没有在ignore_index=True
调用中指定pd.concat
,索引就不会重置(默认为ignore_index=False
)
编辑:
目前尚不清楚您的问题,但是如果您要将该系列添加为新列(而不是彼此叠加),则将最后一行从上方更改为:
p_data = pd.concat(series_list, axis=1)
p_data.columns = self.columns
Edit2:
仍然不是很清楚,但听起来(从您的编辑中)您想将系列转置为行,其中系列的索引成为您的列。即:
series_list = []
for packet in p_rows:
pkt = pd.Series(packet.split(","), dtype='str', index=self.columns)
series_list.append(pkt)
p_data = pd.DataFrame(pd.concat(series_list, axis=1)).T
编辑3:
根据输出图片,在;
上分割时,列表中的最后一个元素为空。例如:
output = """f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None;
f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None;"""
output.split(';')
['f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None',
'\n f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None',
'']
因此,不用for packet in p_rows
来进行for packet in p_rows[:-1]
完整示例:
columns = ['mac', 'rssi', 'voltage', 'temperature', 'ad count', 't since boot', 'other']
output = """f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None;
f1:07:ad:6b:97:c8,-24,2800,23.00,17962365,25509655,None;"""
p_rows = output.split(";")
series_list = []
for packet in p_rows[:-1]:
pkt = pd.Series(packet.strip().split(","), dtype='str', index=columns)
series_list.append(pkt)
p_data = pd.DataFrame(pd.concat(series_list, axis=1)).T
产生
mac rssi voltage temperature ad count t since boot other
0 f1:07:ad:6b:97:c8 -24 2800 23.00 17962365 25509655 None
1 f1:07:ad:6b:97:c8 -24 2800 23.00 17962365 25509655 None
答案 1 :(得分:0)
这是因为您的append语句中p_data
df和pkt
数据之间的键冲突-您需要确保pkt
中的键与{{ 1}}数据框。
通过将p_data
数据框中的列重命名为您在p_data
中看到的数字来解决此问题,或者在添加之前重命名pkt
中的键数据。
编辑:经过进一步讨论,由于输入数据与现有df的顺序相同,因此不会在其中输入约定的列名称。只需将pkt
包裹在pd.DataFrame()
对象周围,并确保在添加数据行时其形状正确,即可获得所需的结果。
pkt