python - 用唯一列表中的后续值替换列值
问题描述
我有一个约 1000 个独特项目的列表
np.random.seed(0)
unique1 = sorted(list(np.random.choice(np.arange(2000), 1000, False)))
和pandas
df.column
大约 1200 万行,其中仅包含此列表中的整数。
df = pd.DataFrame({'a': np.sort(np.random.choice(unique1[1:], 12000000))})
我需要做的是创建一个新列,其中始终包含唯一列表中的前一个元素,而不是原始列中的元素。
我试过这样做,apply
但效率是可笑的,而且有一个普通的循环还不错(在我的系统上大约 2 分钟),但我想知道我是否可以更有效地到达那里(用于说明目的的较小数字) :
np.random.seed(0)
unique1 = sorted(list((np.random.choice(np.arange(20), 10, False))))
df = pd.DataFrame({'a': np.sort(np.random.choice(unique1[1:], 15))})
unique2 = unique1[1:]
df['b'] = df.a.apply(lambda x: unique1[unique2.index(x)])
newCol = []
for item in list(df.a):
newCol.append(unique1[unique2.index(item)])
df['c'] = newCol
print(df, unique1)
a b c
0 2 1 1
1 2 1 1
2 4 2 2
3 6 4 4
4 8 6 6
5 8 6 6
6 8 6 6
7 10 8 8
8 13 10 10
9 13 10 10
10 17 13 13
11 18 17 17
12 18 17 17
13 19 18 18
14 19 18 18 [1, 2, 4, 6, 8, 10, 13, 17, 18, 19]
解决方案
这里的问题是您正在使用list.index
,它对所有唯一值进行线性搜索。
如果你能负担得起构建字典的空间,你可以把它变成一个恒定时间的查找:
unique2 = {value: index for index, value in enumerate(unique1[1:])}
df['b'] = df.a.apply(lambda x: unique1[unique2[x]])
如果你不能(在这种情况下,你应该首先将值保存在数组或切片中而不是列表中......),只要你保持它们排序,你至少可以以对数而不是线性时间搜索使用bisect
或np.searchsorted
:
df['b'] = df.a.apply(lambda x: unique1[np.searchsorted(unique2, x)])
(如果是一个数组而不是一个列表,这会更快unique2
,但只有一个常数因子;它仍然是一个列表的对数时间。)
推荐阅读
- react-native - react-native-audio-toolkit,isPlaying 不起作用
- python - 尝试打印 csv 文件时出现新的 python NameError
- opendaylight - Opendaylight 与 gns3 的集成
- bash - 加载大文件(例如:40M)后,“pwd”命令需要花费大量时间
- javascript - 我需要帮助将 Apex 页面转换为 Lightning 组件
- vb.net - 使用带有规则的预定义结构重写文件名
- sql - 选择字段最大的行,相对于另一个字段
- javascript - 在一个工作簿中创建 3 个工作表(Excel-JS)问题
- android - Android导航组件片段过渡具有白色背景
- ios - 带有 UINavigationControllers 和 UITabBarController 的协调器模式