在 pandas/dask 中有效过滤逗号分隔的字符串

问题描述 投票:0回答:1

我有一些具有以下形状的数据(带标题)

Name, Signal, Date
MyName,1,2,3,4,5,6,7,8,9,10,19-04-2024
MyName,1,2,3,4,5,6,7,8,9,10,19-04-2024

我有兴趣根据“信号”中数组的总和来过滤行。所以我尝试了以下方法:

df = read_csv("my_csv.csv", dtype={"Signal" : "string"}, parse_dates=True)

for i in df["Signal"]:
   t = np.array([int(x) for x in i.split(",")])
   if t.sum() == 100:
       #etc

这种方法会带来一些问题:

  1. 如何记录当前行的索引,然后从我的数据框中过滤/删除它
  2. 这个操作可以加速/更有效地完成吗?我正在考虑分配一个 2d numpy 数组,然后解析数字以仅分配一次,但不确定这会产生影响
  3. 当使用缺乏全局行索引的dask时,是否有更有效的方法来过滤行而不将所有数据分配到numpy数组中?
python pandas csv dask
1个回答
0
投票

根据您的示例数据,我倾向于首先在输入文件上使用正则表达式,然后将其加载到 pandas 的数据框以更改列之间的分隔符(它很简单,高效并跟踪索引)。

注意:这个答案回答了你的前两个问题,我想第三个问题可以使用

.loc
或布尔索引来处理,但不确定,因为我不太理解它。

选项1

  • 使用 Sublime text 程序或任何提供 Regex 引擎的文本编辑器打开输入文件。
  • 单击
    Ctrl+h
    打开查找和替换,然后在查找部分
    (\w+),(.*),(\d{2}-\d{2}-\d{4})
    中输入此模式,并在替换部分
    \1;\2;\3
    中输入此模式。 查找模式将匹配数据的每一行并更改列数据之间的分隔符;您的一行数据将如下所示:
    MyName;1,2,3,4,5,6,7,8,9,10;19-04-2024

注意: 确保手动将列名称之间的分隔符更改为

;
,然后保存输入文件。
您的数据将如下所示:

Name;Signal;Date
MyName;1,2,3,4,5,6,7,8,9,10;19-04-2024
MyName;1,2,3,4,5,6,7,8,9,10;19-04-2024
  • 使用 pandas 的简单代码,您可以获得信号的总和,然后按照您想要的方式进行过滤。

这是示例代码:

temp = pd.read_csv('my_csv copy.csv', sep=";")
df = (
    temp
    .assign(
        summation = lambda df_: df_.Signal.str.split(',').apply(lambda x: sum([int(i) for i in x]))
    )
)

你将得到一个像这样的输出

  Name                Signal        Date     summation
0  MyName  1,2,3,4,5,6,7,8,9,10  19-04-2024         55
1  MyName  1,2,3,4,5,6,7,8,9,10  19-04-2024         55

选项2

您可以打开 CSV 文件并逐行读取它,并将这些行附加到 pandas 数据框。

注意:这对于大数据文件可能效率不高,但由于我不知道您的数据大小,我认为值得测试。
这是示例代码:

df = pd.read_csv('my_csv.csv', dtype={"Signal" : "string"})
# read csv file line by line
output_df = pd.DataFrame(columns=['index','name','Signal', 'Time'])
i = 0
with open('my_csv.csv', 'r') as f:
    line = f.readline()
    for line in f:
        my_list = line.strip().split(',')
        singals =[int(x) for x in my_list[1:-1]]
        summation = sum(singals)
        output_df = pd.concat([
            output_df,
            pd.DataFrame([[i, my_list[0], singals,summation, my_list[-1]]], columns=['index','name','Signal', 'summation','Time'])
        ])
        i+=1
        
output_df = output_df.assign(Time = pd.to_datetime(output_df['Time'], format='%d-%m-%Y'))
output_df

我希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.