将多个文件中的Dask包放入带有

时间:2016-08-22 15:15:50

标签: dataframe dask bag

我收到了一个文件名列表files,其中包含逗号分隔的数据,必须清除这些数据,并进一步扩展包含基于文件名的信息的列。因此,我实现了一个小read_file函数,它可以处理初始清理以及其他列的计算。使用db.from_sequence(files).map(read_file),我将读取函数映射到所有文件,每个文件都获得一个字典列表。

但是,我希望我的包中包含输入文件的每一行作为条目,而不是字典列表。随后,我想将字典的键映射到dask数据帧中的列名。

from dask import bag as db

def read_file(filename):
    ret = []
    with open(filename, 'r') as fp:
        ... # reading line of file and storing result in dict
        ret.append({'a': val_a, 'b': val_b, 'c': val_c})

    return ret

from dask import bag as db
files = ['a.txt', 'b.txt', 'c.txt']
my_bag = db.from_sequence(files).map(read_file)
# a,b,c are the keys of the dictionaries returned by read_file
my_df = my_bag.to_dataframe(columns=['a', 'b', 'c'])

有人可以让我知道我必须更改以运行此代码吗?是否有更合适的不同方法?

编辑: 我创建了三个测试文件a_20160101.txta_20160102.txta_20160103.txt。所有这些都只包含几行,每行包含一个字符串。

asdf
sadfsadf
sadf
fsadff
asdf
sadfasd
fa
sf
ads 
f

之前我在read_file中遇到了一个小错误,但现在,在映射到阅读器之后调用my_bag.take(10)可以正常工作:

([{'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'asdf', 'c': 'XY'}, {'b':    datetime.datetime(2016, 2, 1, 0, 0), 'a': 'sadfsadf', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'sadf', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'fsadff', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'asdf', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'sadfasd', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'fa', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'sf', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'ads', 'c': 'XY'}, {'b': datetime.datetime(2016, 2, 1, 0, 0), 'a': 'f', 'c': 'XY'}],)

然而my_df = my_bag.to_dataframe(columns=['a', 'b', 'c'])及其后 my_df.head(10)仍然提出dask.async.AssertionError: 3 columns passed, passed data had 10 columns

1 个答案:

答案 0 :(得分:1)

您可能需要致电concat

你的文件名包如下所示:

['a.txt', 
 'b.txt', 
 'c.txt']

在你打电话给地图后,你的包看起来像这样:

[[{'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'c': 30}],
 [{'a': 1, 'b': 2, 'c': 3}],
 [{'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'c': 30}]]

每个文件都变成了一个dicts列表。现在你的包就像是一个列表清单。

.to_dataframe方法希望您拥有一个列表。因此,让我们将我们的包连接成一个扁平的dicts集合

my_bag = db.from_sequence(files).map(read_file).concat()

[{'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'c': 30},
 {'a': 1, 'b': 2, 'c': 3},
 {'a': 1, 'b': 2, 'c': 3}, {'a': 10, 'b': 20, 'c': 30}]