【发布时间】:2021-07-26 14:35:32
【问题描述】:
我有两列 col1 和 col2
我正在尝试创建键列以显示 a 和 b 与 b 和 a
问题代码:
import pandas as pd
pd.DataFrame({'Col1':['a','c','b','e'],
'Col2':['b','d','a','f']})
【问题讨论】:
标签: python pandas combinations
我有两列 col1 和 col2
我正在尝试创建键列以显示 a 和 b 与 b 和 a
问题代码:
import pandas as pd
pd.DataFrame({'Col1':['a','c','b','e'],
'Col2':['b','d','a','f']})
【问题讨论】:
标签: python pandas combinations
试试frozenset
df['out'] = df.agg(frozenset,1).str.join(sep='')
Out[220]:
0 ab
1 dc
2 ab
3 ef
dtype: object
【讨论】:
TypeError: 'frozenset' type is unordered,但适用于 1.2.2
df.agg(frozenset, axis=1).apply(sorted).str.join('') 可能更适合排序,因为它给了我“ba”而不是“ab”
使用 numpy 对字符串进行排序,然后加入/求和。无论值在列中出现的顺序如何,这都会创建一个唯一键。
import numpy as np
df['key'] = np.sort(df.to_numpy(), axis=1).sum(1)
# Col1 Col2 key
#0 a b ab
#1 c d cd
#2 b a ab
#3 e f ef
如果您有兴趣,numpy.sort 是执行此操作的高效方式。任何 .agg 或 .apply 都会减少行上的慢循环,因此随着 DataFrame 变大,它们的扩展性会更差。相对于numpy.sort,其他方法通常至少慢一个数量级。
import perfplot
import pandas as pd
import numpy as np
from string import ascii_lowercase
def apply_sorted(df):
return df.apply(sorted, 1).str.join(sep='')
def numpy_sort(df):
return pd.Series(np.sort(df.to_numpy(), axis=1).sum(1))
perfplot.show(
setup=lambda N: pd.DataFrame({'Col1': np.random.choice([*ascii_lowercase], N),
'Col2': np.random.choice([*ascii_lowercase], N)}),
kernels=[
lambda df: apply_sorted(df),
lambda df: numpy_sort(df),
],
labels=['apply_sorted', 'numpy_sort'],
n_range=[2 ** k for k in range(25)],
equality_check=lambda x,y: x.compare(y).empty,
relative_to=1,
xlabel='len(df)'
)
【讨论】:
我会使用sorted 内置函数来完成这项任务
import pandas as pd
df = pd.DataFrame({'Col1':['a','c','b','e'],'Col2':['b','d','a','f']})
df['key'] = df.apply(sorted,1).str.join(sep='')
print(df)
输出
Col1 Col2 key
0 a b ab
1 c d cd
2 b a ab
3 e f ef
解释:它确实按字典顺序对每一行进行排序,然后连接这些元素。假设:Col1 的每个元素都是单个字符,Col2 的每个元素都是单个字符。
【讨论】: