Неустойчивая + синхронизация - это безупречное доказательство того, что операция (оператор) полностью атомарна, которая включает в себя несколько инструкций для CPU.
Скажем, например: volatile int i = 2; i ++, который не что иное, как i = i + 1; что делает i значением 3 в памяти после выполнения этого оператора. Это включает в себя чтение существующего значения из памяти для i (которое равно 2), загрузка в регистр накопителя ЦП и выполнение вычисления путем увеличения существующего значения с помощью одного (2 + 1 = 3 в аккумуляторе), а затем записи назад, обратно в память. Эти операции не являются достаточно атомными, хотя значение i является изменчивым. i volatile гарантирует только то, что SINGLE чтение / запись из памяти является атомарным, а не с MULTIPLE. Следовательно, нам нужно синхронизировать также вокруг i ++, чтобы он был логическим утверждением с дураком. Помните, что оператор содержит несколько операторов.
Надеюсь, что объяснение достаточно ясное.
Если у вас есть ключ, который повторяется для каждой строки, вы можете создать декартово произведение с использованием слияния (как в SQL).
from pandas import DataFrame, merge
df1 = DataFrame({'key':[1,1], 'col1':[1,2],'col2':[3,4]})
df2 = DataFrame({'key':[1,1], 'col3':[5,6]})
merge(df1, df2,on='key')[['col1', 'col2', 'col3']]
См. здесь документацию: http://pandas.pydata.org/pandas-docs/stable/merging.html#brief-primer-on-merge-methods-relational-algebra
Минимальный код, необходимый для этого. Создайте общий «ключ» для декартовой слияния двух:
df1['key'] = 0
df2['key'] = 0
df_cartesian = df1.merge(df2, how='outer')
Я считаю, что использование pandas MultiIndex является лучшим инструментом для работы. Если у вас есть список списков lists_list
, вызовите pd.MultiIndex.from_product(lists_list)
и повторите результат (или используйте его в индексе DataFrame).
Используйте pd.MultiIndex.from_product
в качестве индекса в противном случае пустой фреймворк, а затем сбросьте его индекс, и все готово.
a = [1, 2, 3]
b = ["a", "b", "c"]
index = pd.MultiIndex.from_product([a, b], names = ["a", "b"])
pd.DataFrame(index = index).reset_index()
out:
a b
0 1 a
1 1 b
2 1 c
3 2 a
4 2 b
5 2 c
6 3 a
7 3 b
8 3 c
С цепью метода:
product = (
df1.assign(key=1)
.merge(df2.assign(key=1), on="key")
.drop("key", axis=1)
)
Это не приведет к конкуренции в кодовом гольф-соревновании и заимствует предыдущие ответы, но ясно показывает, как добавляется ключ и как работает соединение. Это создает 2 новых фрейма данных из списков, а затем добавляет ключ для декартового продукта.
Моим вариантом использования было то, что мне понадобился список всех идентификаторов магазина в течение каждой недели в моем списке. Итак, я создал список всех недель, которые я хотел иметь, а затем список всех идентификаторов хранилища, которые я хотел сопоставить им.
Слияние, которое я выбрал влево, но будет семантически таким же, как внутренний в этой настройке. Вы можете увидеть это в документации по слиянию , в которой говорится, что он имеет декартово произведение, если комбинация клавиш появляется более двух раз в обеих таблицах - это то, что мы установили.
days = pd.DataFrame({'date':list_of_days})
stores = pd.DataFrame({'store_id':list_of_stores})
stores['key'] = 0
days['key'] = 0
days_and_stores = days.merge(stores, how='left', on = 'key')
days_and_stores.drop('key',1, inplace=True)
Если у вас нет перекрывающихся столбцов, не хотите их добавлять, а индексы кадров данных могут быть отброшены, это может быть проще:
df1.index[:] = df2.index[:] = 0
df_cartesian = df1.join(df2, how='outer')
df_cartesian.index[:] = range(len(df_cartesian))
В качестве альтернативы можно полагаться на декартово произведение, предоставляемое itertools: itertools.product
, что позволяет избежать создания временного ключа или изменения индекса:
import numpy as np
import pandas as pd
import itertools
def cartesian(df1, df2):
rows = itertools.product(df1.iterrows(), df2.iterrows())
df = pd.DataFrame(left.append(right) for (_, left), (_, right) in rows)
return df.reset_index(drop=True)
Быстрая проверка:
In [46]: a = pd.DataFrame(np.random.rand(5, 3), columns=["a", "b", "c"])
In [47]: b = pd.DataFrame(np.random.rand(5, 3), columns=["d", "e", "f"])
In [48]: cartesian(a,b)
Out[48]:
a b c d e f
0 0.436480 0.068491 0.260292 0.991311 0.064167 0.715142
1 0.436480 0.068491 0.260292 0.101777 0.840464 0.760616
2 0.436480 0.068491 0.260292 0.655391 0.289537 0.391893
3 0.436480 0.068491 0.260292 0.383729 0.061811 0.773627
4 0.436480 0.068491 0.260292 0.575711 0.995151 0.804567
5 0.469578 0.052932 0.633394 0.991311 0.064167 0.715142
6 0.469578 0.052932 0.633394 0.101777 0.840464 0.760616
7 0.469578 0.052932 0.633394 0.655391 0.289537 0.391893
8 0.469578 0.052932 0.633394 0.383729 0.061811 0.773627
9 0.469578 0.052932 0.633394 0.575711 0.995151 0.804567
10 0.466813 0.224062 0.218994 0.991311 0.064167 0.715142
11 0.466813 0.224062 0.218994 0.101777 0.840464 0.760616
12 0.466813 0.224062 0.218994 0.655391 0.289537 0.391893
13 0.466813 0.224062 0.218994 0.383729 0.061811 0.773627
14 0.466813 0.224062 0.218994 0.575711 0.995151 0.804567
15 0.831365 0.273890 0.130410 0.991311 0.064167 0.715142
16 0.831365 0.273890 0.130410 0.101777 0.840464 0.760616
17 0.831365 0.273890 0.130410 0.655391 0.289537 0.391893
18 0.831365 0.273890 0.130410 0.383729 0.061811 0.773627
19 0.831365 0.273890 0.130410 0.575711 0.995151 0.804567
20 0.447640 0.848283 0.627224 0.991311 0.064167 0.715142
21 0.447640 0.848283 0.627224 0.101777 0.840464 0.760616
22 0.447640 0.848283 0.627224 0.655391 0.289537 0.391893
23 0.447640 0.848283 0.627224 0.383729 0.061811 0.773627
24 0.447640 0.848283 0.627224 0.575711 0.995151 0.804567