在 Python 中列出交集和部分字符串匹配
List intersection and partial string matching in Python
所以我有 2 个列表,第一个来自我的数据集,包含 'yyyy-mm-dd hh:mm' 格式的日期时间,名为 times
。示例:
'2010-01-01 00:00', '2010-01-01 00:15', '2010-01-01 00:30', ...,
另一个是所有唯一年月组合的列表,名为year_and_month
。示例:
'2010-01', '2010-02', '2010-03', '2010-04',
所以我尝试提取原始数据集中年月组合的所有索引。我使用最糟糕的方式(python 中的新方法)来做到这一点,即
each_member_indices = []
for i in range(len(year_and_month)):
item_ind = []
for j in range(times.shape[0]):
if year_and_month[i] in times[j]:
item_ind.append(j)
each_member_indices.append(item_ind)
现在,这是花这么多时间工作的致命伤。所以我想稍微优化一下,因此我正在研究一些实现,例如
Find intersection of two lists? and Python: Intersection of full string from list with partial string 问题在于
res_1 = [val for val in year_and_month if val in times]
生成一个空列表,而
res_1 = [val for val in year_and_month if val in times[0]]
至少让出第一个成员。
有什么想法吗?
编辑:
我只需要来自名为 times
的原始数据集的元素的索引对应于 year_and_month
列表的唯一年月对。因此,根据要求,样本输出将是
[[0, 1, 2, 3,...],[925, 926, ...],...]
第一个子列表包含 2010 年一月对的索引,第二个子列表包含 2010 年二月对的索引,依此类推。
也许尝试使用 any?
[val for val in year_and_month if any(val in t for t in times)]
为什么不用字典创建一个新结构并按 year_and_month 排序?
result = {}
for i, v in enumerate(times):
result.setdefault(v[:7], []).append(i)
for i in year_and_month:
print(i, result[i]) #will print the year_month with all the indices of that year_month
要在线性时间内做到这一点,您可以构建一个查找字典,将年份和月份组合映射到索引。您还可以使用 collections.defaultdict
使其更容易一些:
from collections import defaultdict
d = defaultdict(list)
for i, v in enumerate(times):
d[v[:7]].append(i)
然后您可以使用列表理解创建结果列表:
result = [d[x] for x in year_and_month]
演示:
>>> from collections import defaultdict
>>> times = ['2010-01-01 00:00', '2010-01-01 00:15', '2010-02-01 00:30', '2010-03-01 00:00']
>>> year_and_month = ['2010-01', '2010-02', '2010-03', '2010-04']
>>> d = defaultdict(list)
>>> for i, v in enumerate(times):
... d[v[:7]].append(i)
...
>>> dict(d)
{'2010-01': [0, 1], '2010-02': [2], '2010-03': [3]}
>>> [d[x] for x in year_and_month]
[[0, 1], [2], [3], []]
好的,这给出了共同的元素:
ls = str(times)
r = [x for x in year_and_month if (x in ls)]
print r
所以我有 2 个列表,第一个来自我的数据集,包含 'yyyy-mm-dd hh:mm' 格式的日期时间,名为 times
。示例:
'2010-01-01 00:00', '2010-01-01 00:15', '2010-01-01 00:30', ...,
另一个是所有唯一年月组合的列表,名为year_and_month
。示例:
'2010-01', '2010-02', '2010-03', '2010-04',
所以我尝试提取原始数据集中年月组合的所有索引。我使用最糟糕的方式(python 中的新方法)来做到这一点,即
each_member_indices = []
for i in range(len(year_and_month)):
item_ind = []
for j in range(times.shape[0]):
if year_and_month[i] in times[j]:
item_ind.append(j)
each_member_indices.append(item_ind)
现在,这是花这么多时间工作的致命伤。所以我想稍微优化一下,因此我正在研究一些实现,例如 Find intersection of two lists? and Python: Intersection of full string from list with partial string 问题在于
res_1 = [val for val in year_and_month if val in times]
生成一个空列表,而
res_1 = [val for val in year_and_month if val in times[0]]
至少让出第一个成员。
有什么想法吗?
编辑:
我只需要来自名为 times
的原始数据集的元素的索引对应于 year_and_month
列表的唯一年月对。因此,根据要求,样本输出将是
[[0, 1, 2, 3,...],[925, 926, ...],...]
第一个子列表包含 2010 年一月对的索引,第二个子列表包含 2010 年二月对的索引,依此类推。
也许尝试使用 any?
[val for val in year_and_month if any(val in t for t in times)]
为什么不用字典创建一个新结构并按 year_and_month 排序?
result = {}
for i, v in enumerate(times):
result.setdefault(v[:7], []).append(i)
for i in year_and_month:
print(i, result[i]) #will print the year_month with all the indices of that year_month
要在线性时间内做到这一点,您可以构建一个查找字典,将年份和月份组合映射到索引。您还可以使用 collections.defaultdict
使其更容易一些:
from collections import defaultdict
d = defaultdict(list)
for i, v in enumerate(times):
d[v[:7]].append(i)
然后您可以使用列表理解创建结果列表:
result = [d[x] for x in year_and_month]
演示:
>>> from collections import defaultdict
>>> times = ['2010-01-01 00:00', '2010-01-01 00:15', '2010-02-01 00:30', '2010-03-01 00:00']
>>> year_and_month = ['2010-01', '2010-02', '2010-03', '2010-04']
>>> d = defaultdict(list)
>>> for i, v in enumerate(times):
... d[v[:7]].append(i)
...
>>> dict(d)
{'2010-01': [0, 1], '2010-02': [2], '2010-03': [3]}
>>> [d[x] for x in year_and_month]
[[0, 1], [2], [3], []]
好的,这给出了共同的元素:
ls = str(times)
r = [x for x in year_and_month if (x in ls)]
print r