在 pandas 数据框中创建新列作为其他列的总和排列
Creating new columns in pandas dataframe as summed permutations of other columns
希望这个简单的解释能够理解我正在尝试做的事情。假设我有一个 Pandas 数据框,其中包含以下列:
A B C D E
1 2 4 6 4
3 4 1 2 3
4 7 4 1 4
有谁知道我可以在 table 中创建一组新的列的方法(无需手动操作),对列的排列子集求和?我一直在进行一些搜索,但没有任何运气,因为这是一个相当具体的查询。
例如,如果我想要 5 列中 3 列子集的总和的所有组合 - 一些额外的行可能如下所示:
ABC ACE BDE
7 9 12
8 7 9
15 12 12
...等等(在这种情况下会有 5C3 = 10 行 - 但我实际上正在查看 7C4 示例)
提前致谢!
使用 combinations
代替 permutations
并将元组的每个值加在一起:
from itertools import combinations
cc = list(combinations(df.columns,3))
df = pd.concat([df.loc[:, c].sum(axis=1) for c in cc], axis=1, keys=cc)
df.columns = df.columns.map(''.join)
print (df)
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
或者作为替代:
import itertools
pd.DataFrame({'{}{}{}'.format(a, b, c): df[a] + df[b] + df[c]
for a, b, c in itertools.combinations(df.columns, 3)})
输出:
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
使用底层 numpy 数组提高效率。
from itertools import combinations
a = df.to_numpy()
df2 = pd.DataFrame(np.vstack([a[:,list(c)].sum(1)
for c in combinations(range(df.shape[1]), 3)
]).T,
columns=map(''.join, combinations(df, 3))
)
输出:
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
注意。这比其他基于 pandas 的解决方案快 运行 ~10 倍。
因为觉得很有意思,所以比较了三个方案
耶斯莱尔
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
cc = list(combinations(df.columns,3))
df = pd.concat([df.loc[:, c].sum(axis=1) for c in cc], axis=1, keys=cc)
df.columns = df.columns.map(''.join)
df
结果:
5.99 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
莫兹威
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
a = df.to_numpy()
df2 = pd.DataFrame(np.vstack([a[:,list(c)].sum(1)
for c in combinations(range(df.shape[1]), 3)
]).T,
columns=map(''.join, combinations(df, 3))
)
df2
结果:
458 µs ± 868 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Marco_CH
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
df = pd.DataFrame({'{}{}{}'.format(a, b, c): df[a] + df[b] + df[c]
for a, b, c in itertools.combinations(df.columns, 3)})
df
结果:
2.25 ms ± 14.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
因此,如果性能是关键,那么 mozways 解决方案是迄今为止最好的。如果性能不是那么重要,那么我们可以针对每种偏好提供三种不同的方法:-)
希望这个简单的解释能够理解我正在尝试做的事情。假设我有一个 Pandas 数据框,其中包含以下列:
A B C D E
1 2 4 6 4
3 4 1 2 3
4 7 4 1 4
有谁知道我可以在 table 中创建一组新的列的方法(无需手动操作),对列的排列子集求和?我一直在进行一些搜索,但没有任何运气,因为这是一个相当具体的查询。
例如,如果我想要 5 列中 3 列子集的总和的所有组合 - 一些额外的行可能如下所示:
ABC ACE BDE
7 9 12
8 7 9
15 12 12
...等等(在这种情况下会有 5C3 = 10 行 - 但我实际上正在查看 7C4 示例)
提前致谢!
使用 combinations
代替 permutations
并将元组的每个值加在一起:
from itertools import combinations
cc = list(combinations(df.columns,3))
df = pd.concat([df.loc[:, c].sum(axis=1) for c in cc], axis=1, keys=cc)
df.columns = df.columns.map(''.join)
print (df)
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
或者作为替代:
import itertools
pd.DataFrame({'{}{}{}'.format(a, b, c): df[a] + df[b] + df[c]
for a, b, c in itertools.combinations(df.columns, 3)})
输出:
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
使用底层 numpy 数组提高效率。
from itertools import combinations
a = df.to_numpy()
df2 = pd.DataFrame(np.vstack([a[:,list(c)].sum(1)
for c in combinations(range(df.shape[1]), 3)
]).T,
columns=map(''.join, combinations(df, 3))
)
输出:
ABC ABD ABE ACD ACE ADE BCD BCE BDE CDE
0 7 9 7 11 9 11 12 10 12 14
1 8 9 10 6 7 8 7 8 9 6
2 15 12 15 9 12 9 12 15 12 9
注意。这比其他基于 pandas 的解决方案快 运行 ~10 倍。
因为觉得很有意思,所以比较了三个方案
耶斯莱尔
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
cc = list(combinations(df.columns,3))
df = pd.concat([df.loc[:, c].sum(axis=1) for c in cc], axis=1, keys=cc)
df.columns = df.columns.map(''.join)
df
结果:
5.99 ms ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
莫兹威
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
a = df.to_numpy()
df2 = pd.DataFrame(np.vstack([a[:,list(c)].sum(1)
for c in combinations(range(df.shape[1]), 3)
]).T,
columns=map(''.join, combinations(df, 3))
)
df2
结果:
458 µs ± 868 ns per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Marco_CH
%%timeit
df = pd.DataFrame({"A":[1,3,4],
"B":[2,4,7],
"C":[4,1,4],
"D":[6,2,1],
"E":[4,3,4]})
df = pd.DataFrame({'{}{}{}'.format(a, b, c): df[a] + df[b] + df[c]
for a, b, c in itertools.combinations(df.columns, 3)})
df
结果:
2.25 ms ± 14.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
因此,如果性能是关键,那么 mozways 解决方案是迄今为止最好的。如果性能不是那么重要,那么我们可以针对每种偏好提供三种不同的方法:-)