Polars, вычисление нового столбца путем перекрестных ссылок на два кадра данных ⇐ Python

Программы на Python
Anonymous
Polars, вычисление нового столбца путем перекрестных ссылок на два кадра данных

Сообщение Anonymous »

Прежде всего, я должен сказать, что я впервые использую какой-либо модуль DataFrame.
Мне нужно обработать результаты моделирования FEM, которые я загрузил в фрейм данных Polars, которые создают два Кадры данных:

Код: Выделить всё

nodes_df = pl.DataFrame(
{"node":[1,2,3,4,5,6,7,8,9,10],
"x":[4.5,-4.6, 3.8,-3.8, 2.1,-9.3, 1.5,-6.7, 0.0, 3.6],
"y":[9.8,-9.9, 8.2,-8.3, 4.6,-2.0, 1.4,-6.1, 0.0, 1.0],
"z":[0.0,0.0,8.8,8.8,1.2,1.2,5.5,5.5,5.5,0.0,]})

elements = [1, 2, 3]
elements_df = pl.DataFrame(
{
"element": elements,
"N_1": [1, 1, 1],
"N_2": [2, 2, 2],
"N_3": [3, 3, 3],
"N_4": [4, 4, 4],
"N_5": [5, 5, 5],
"N_6": [6, 6, 6],
"N_7": [7, 7, 7],
"N_8": [8, 8, 8],
"N_9": [9, 9, 9],
"N_10": [10, 10, 10],
}
)
Эти данные представляют значения 10 узловых элементов C3D10 следующим образом:
[img]https: //i.sstatic.net/zUxP4.png[/img]

elements_dfсодержит определения для всех элементов, где столбцы N_{x} de id своих узлов (порядок узлов важен), поэтому каждый элемент всегда имеет 10 разных узлов. В nodes_df может быть больше столбцов с другими результатами моделирования, которые я обработаю позже. Идея состоит в том, чтобы передать результаты, хранящиеся в nodes_df, в центроид элемента.
В примере есть 10 (поддельных) узлов и 3 (равны поддельным) элемента, это просто выборочные данные в каждой строке будут разными. Где nodes_df имеет столбец «node» для представления идентификатора узла, а x,y,z — координаты узла. В elements_df есть столбец "element" для идентификатора и столбцы N_ для идентификаторов узлов. Во-первых, я не знаю, лучше или хуже эта схема, чем наличие одного столбца со списком узлов в одном столбце, учитывая производительность и простоту использования фрейма данных, у меня нет проблем изменить схему.
Но мне нужно сделать перекрестную ссылку на оба фрейма данных, чтобы выполнить несколько вычислений результатов. Для начала мне нужно вычислить центроид элемента.
Поскольку я новичок в dataframe, я сделал это, чтобы прояснить свою точку зрения, но я знаю, что это худший код DataFrame, который кто-либо может сделать. напишите:

Код: Выделить всё

def coords(nodes: list):
# get nodes coordinates for a node list
return (
nodes_df.filter(pl.col("node").is_in(nodes))
.select((pl.col(("x", "y", "z"))))
.mean()
)

def centroid(el_id: int):
# get the first four nodes ids for el with id = el_id
nodes = elements_df.filter(pl.col("element") == el_id).to_numpy()[0][:4]
return coords(nodes)

# loop over all elements and create new dataframe
# or maybe use this schema:
# _tmp = {"element": [], "x": [],"y": [],"z": []}
_tmp = {"element": [], "centroid": []}
for el in elements:
c = centroid(el).to_numpy()[0]
_tmp["element"].append(el)
_tmp["centroid"].append(c)
# _tmp["x"].append(c[0])
# _tmp["y"].append(c[1])
# _tmp["z"].append(c[2])

# concat dataframes to add the new "centroid" column
elements_df = pl.concat((elements_df, pl.DataFrame(_tmp)), how="align")
Результаты будут примерно такими:

Код: Выделить всё

shape: (3, 12)
┌─────────┬─────┬─────┬─────┬───┬─────┬─────┬──────┬───────────────────────────┐
│ element ┆ N_1 ┆ N_2 ┆ N_3 ┆ … ┆ N_8 ┆ N_9 ┆ N_10 ┆ centroid                  │
│ ---     ┆ --- ┆ --- ┆ --- ┆   ┆ --- ┆ --- ┆ ---  ┆ ---                       │
│ i64     ┆ i64 ┆ i64 ┆ i64 ┆   ┆ i64 ┆ i64 ┆ i64  ┆ list[f64]                 │
╞═════════╪═════╪═════╪═════╪═══╪═════╪═════╪══════╪═══════════════════════════╡
│ 1       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 8   ┆ 9   ┆ 10   ┆ [1.233333, 2.7, 2.933333] │
│ 2       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 8   ┆ 9   ┆ 10   ┆ [1.233333, 2.7, 2.933333] │
│ 3       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 8   ┆ 9   ┆ 10   ┆ [1.233333, 2.7, 2.933333] │
└─────────┴─────┴─────┴─────┴───┴─────┴─────┴──────┴───────────────────────────┘
или прокомментированную схему:

Код: Выделить всё

┌─────────┬─────┬─────┬─────┬───┬──────┬──────────┬─────┬──────────┐
│ element ┆ N_1 ┆ N_2 ┆ N_3 ┆ … ┆ N_10 ┆ x        ┆ y   ┆ z        │
│ ---     ┆ --- ┆ --- ┆ --- ┆   ┆ ---  ┆ ---      ┆ --- ┆ ---      │
│ i64     ┆ i64 ┆ i64 ┆ i64 ┆   ┆ i64  ┆ f64      ┆ f64 ┆ f64      │
╞═════════╪═════╪═════╪═════╪═══╪══════╪══════════╪═════╪══════════╡
│ 1       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 10   ┆ 1.233333 ┆ 2.7 ┆ 2.933333 │
│ 2       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 10   ┆ 1.233333 ┆ 2.7 ┆ 2.933333 │
│ 3       ┆ 1   ┆ 2   ┆ 3   ┆ … ┆ 10   ┆ 1.233333 ┆ 2.7 ┆ 2.933333 │
└─────────┴─────┴─────┴─────┴───┴──────┴──────────┴─────┴──────────┘
Я уверен, что то, что я сделал здесь, можно сделать прямо в поляре, но не знаю, с чего начать. Это мой самый простой вариант, но мне придется вычислять другие вещи, используя перекрестные ссылки на оба фрейма данных, поэтому я хочу научиться это делать. А также ищу советы по моим схемам

Подробнее здесь: https://stackoverflow.com/questions/778 ... dataframes

Вернуться в «Python»