将DataFrame数组转换为Single DataFrame

时间:2016-04-08 20:19:25

标签: python python-2.7 pandas multiprocessing

TLDR:我不知道如何获取DataFrame数组并在其周围构建MultiIndex。

TLDR 2 :根据我的研究,建议处理返回结果,而不是尝试使用Pool().Map()中的全局/单个/共享DataFrame。如果有人有办法分享它,我会全力以赴。

我正在尝试合并MultiIndexPool()函数返回的Map() Pandas DataFrame数组。

p = Pool()
results = p.map(run_experiment, experiment_collection)

Pool().map()以数组形式返回。假设该过程返回数组为1000 DataFrame,第一个索引为[0:5],第二个[0:50]

我想要的是创建一个最终输出,它是一个单独的数据框架,可以将每个实验分开,[0:1000] / [0:5] / [0:50]

我知道如何使用np.zeros_like创建MultiIndex,然后填充DataFrame,但我不知道如何获取DataFrame数组并在其周围构建MultiIndex。

rounds = range(0,1000)
levels = [... some set of levels ...]
labels = [... some set of labels ...]
iterables = [rounds, labels, levels]

names = ['round', 'label', 'values']
index = pd.MultiIndex.from_product(iterables, names=names)

index_names = [... some set of index names...]
empty_df = pd.DataFrame(
              np.zeros_like(np.random.randn(5, 50000)),
              index=index_names,
              columns=index
             )
             .sort_index()
             .sort_index(axis=1)

在我的第一个示例中,results是一个由levels / labels组成的MultiIndex DataFrame数组。我要做的是创建一个最终的DataFrame,它将顶层(一个包含所有这些DataFrame的数组)替换为一个新的索引。

当我尝试

p = Pool()
results = pd.DataFrame(
              p.map(run_experiment, experiment_collection),
              index=index_names,
              columns=index
             )
             .sort_index()
             .sort_index(axis=1)

我收到ValueError: Shape of passed values is (1, 1000), indices imply (shape of intended index),这很有意义,因为它是一个包含1000个数据框架的数组。

如果我连接(感觉这是更好的方式)

results = pd.concat(p.map(run_experiment, experiment_collection))

我使用levels / labels获取了一个DataFrame,但没有round

iterables = [rounds, labels, levels]
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
       keys=None, levels=None, names=None, verify_integrity=False)

我不确定我应该在这里操作哪些选项(键,级别,名称)以使我的rounds重新进入DataFrame。

results = pd.concat(
              p.map(run_experiment, experiment_collection),
              levels=iterables,
              names=names,
              axis=1
          )

让我非常接近我想要的格式,但没有round

如果需要,我可以更具体,但不完全确定在获得答案时还有什么其他帮助。

2 个答案:

答案 0 :(得分:0)

缺少更好的答案,我正在重新创建原始DataFrame,并迭代Pool().Map()返回的结果,将每个列表位置插入DataFrame。似乎必须有更好的方法,但我想不到它。

p = Pool()
results = p.map(run_experiment, experiment_collection)

final_df = pd.DataFrame(
            np.zeros_like(np.random.randn(5, 50000)),
            index=index_names,
            columns=index
           )
           .sort_index()
           .sort_index(axis=1)

for result in results:
  final_df[increment_value] = result

答案 1 :(得分:0)

有几种好方法可以做到这一点:

1)如果您从一堆Series对象开始:     您将系列对象名称参数设置为元组。然后使用pd.concat([series list],axis = 1)

2)如果您有一个数据帧的单级映射,则可以使用pd.concat可以接受dict作为其第一个参数的事实。 E.g。

pd.concat({A:df1, B:df2}, axis=1)

将创建一个多级索引,其中A,B为顶级,df的列为第二级。虽然您无法嵌套dicts,但您可以多次执行此操作来构建任意深度的索引。

3)您可以在DF上使用Dataframe构造函数,但将元组列表作为列名称传递。 E.F.如果你有一个带有A,B列的df你做df_new = pd.DataFrame(df,columns = [(“Foo”,“A”),(“Foo”,“B”)])这将创建一个具有多级索引的新df,您可以单独为您的df执行此操作,然后将它们连接起来。 Pandas会适当地将两个数据帧与具有相同级别数的索引连接起来。