У меня есть фрейм данных (df) с последовательностью вдоль осей x и y. Я хотел бы показать смежность в значениях.
Например, со следующим фреймом данных:
Визуально:
Столбец x следует за 0-3, поскольку значения y перемещаются вверх по оси y 0-1. Я хотел бы показать смежность, но не уверен в правильном форматировании. Желаемый результат показан ниже с максимум 3 соседними значениями.
Я могу получить результаты примерно так:
max_x = df['x'].max()
for i in range(max_x):
df['adjacent_value_1'].iloc[i] = df['value'].iloc[i-1]
test.append(df.copy())
С предоставленным вами кадром данных:
import pandas as pd
df = pd.DataFrame(
{
"x": [0, 1, 2, 3, 0, 1, 2, 3],
"y": [0, 0, 0, 0, 1, 1, 1, 1],
"value": ["red", "pink", "green", "blue", "yellow", "orange", "blue", "purple"],
}
)
Вот один из способов:
# Find adjacent values
for i, t in enumerate([(-1, 0), (0, -1), (1, 0), (0, 1)]):
df[f"adjacent_{i}"] = df.apply(
lambda df_: df.loc[
(df["x"] == df_["x"] + t[0]) & (df["y"] == df_["y"] + t[1]), "value"
].values,
axis=1,
)
# Get values and add them to a list in temporary column
for col in df.columns:
if not col.startswith("adjacent"):
continue
df[col] = df[col].map(lambda x: x[0] + "," if x.size > 0 else pd.NA)
df["temp"] = (
df[[f"adjacent_{i}" for i in range(4)]].fillna("").sum(axis=1).str.split(",")
)
# Reorder dataframe to move nan values to the most right
df = (
pd.DataFrame(
df["temp"].values.tolist(), index=df.set_index(["x", "y", "value"]).index
)
.add_prefix("adjacent_")
.replace("", pd.NA)
.dropna(how = "all", axis=1)
.reset_index()
)
# Rename columns
df.columns = ["x", "y", "value"] + [f"adjacent_{i+1}" for i in range(3)]
Затем:
print(df)
# Output
x y value adjacent_1 adjacent_2 adjacent_3
0 0 0 red pink yellow <NA>
1 1 0 pink red green orange
2 2 0 green pink blue blue
3 3 0 blue green purple <NA>
4 0 1 yellow red orange <NA>
5 1 1 orange yellow pink blue
6 2 1 blue orange green purple
7 3 1 purple blue blue <NA>