pandas:为每个索引值和外部列表值的组合创建一行

pandas: create a row per combination of index value and external list value

我正在尝试在数据框中创建一行,该行表示 df 的索引与列表中的值之间的唯一组合。

一个简短的例子比很多单词更明确!

           Id
0    16342939
1    16346727

和列表

Location = ['DC1', 'DC2', 'store1','store2']

我想要实现的是:

           Id    Loc
0    16342939    DC1
0    16342939    DC2
0    16342939 store1
0    16342939 store2
1    16346727    DC1
1    16346727    DC2
1    16346727 store1
1    16346727 store2

我想问的是在 python 中我应该使用什么工具来做到这一点。我思考并搜索了 itertoolscombinations。但它似乎并不能解决问题。我也想过合并列表,但是也没用。

非常感谢您推荐使用的工具!

您还可以使用 pyjanitor 库中的 expand_grid

others = {"Id": df.Id.array, 'Loc': Location}

In [87]: janitor.expand_grid(others = others)
Out[87]: 
         Id     Loc
0  16342939     DC1
1  16342939     DC2
2  16342939  store1
3  16342939  store2
4  16346727     DC1
5  16346727     DC2
6  16346727  store1
7  16346727  store2

您可以使用 numpy 提高速度:

left = np.repeat(df.Id.array, len(Location))
right = np.resize(Location, len(df)*len(Location))
combo =zip(['Id', 'Loc'],  map(pd.Series, (left, right)))
pd.concat(dict(combo), axis = 'columns')
         Id     Loc
0  16342939     DC1
1  16342939     DC2
2  16342939  store1
3  16342939  store2
4  16346727     DC1
5  16346727     DC2
6  16346727  store1
7  16346727  store2

您可以使用列表推导式和 pandas 爆炸函数来做到这一点。

首先使用位置列表填充“位置”列。为此,您需要使用列表理解,否则 pandas 将尝试使用单个列表条目而不是整个列表来填充列的行。列表理解的示例代码如下:

df['Loc'] = [Location for i in range(len(df))]

然后可以使用explode函数拆分 pandas explode函数将列表数据拆分成具有相同“Id”值的单独行。示例代码如下:

df = df.explode('Loc')

最终结果如下:

         Id     Loc
0  16342939     DC1
0  16342939     DC2
0  16342939  store1
0  16342939  store2
1  16346727     DC1
1  16346727     DC2
1  16346727  store1
1  16346727  store2

您可以使用 pandas.DataFrame.merge:

>>> df.merge(pd.Series(Location, name = 'Loc'), how = "cross")
         Id     Loc
0  16342939     DC1
1  16342939     DC2
2  16342939  store1
3  16342939  store2
4  16346727     DC1
5  16346727     DC2
6  16346727  store1
7  16346727  store2