Ich habe den folgenden DataFrame namens df:
Numerisch | Land1 | Land2 | Land3 | Land4 | Land5 |
---|---|---|---|---|---|
5 | Ja | Nein | Nein | Ja | Ja |
zehn | Nein | Ja | Ja | Nein | Ja |
6 | Ja | Nein | Nein | Ja | Nein |
acht | Ja | Nein | Ja | Ja | Ja |
neun | Nein | Ja | Nein | Ja | Nein |
Lösung des Problems
Dies kann erreicht werden, indem die Spalten mit Ja maskiert und dann verwendet np.einsum
werden, um True oder False für jede Kombination von zwei Spalten für jede Zeile zu erhalten. Multiplizieren Sie mit den Werten in der numerischen Spalte und sum
über der Achse, die die Zeilen darstellt (bei meiner Wahl der Indizes einsum
ist es die letzte). Erstellen Sie wie gewünscht einen Datenrahmen mit Index und Spalten
m = df.drop(['Numeric'], axis=1).eq('Yes')
print(m)
# Country1 Country2 Country3 Country4 Country5
# 0 True False False True True
# 1 False True True False True
# 2 True False False True False
# 3 True False True True True
# 4 False True False True False
res = pd.DataFrame(
data=(np.einsum('ij,ik->jki',m,m)
*df['Numeric'].to_numpy()[None,:]
).sum(axis=-1),
index=m.columns,
columns = m.columns
)
print(res)
# Country1 Country2 Country3 Country4 Country5
# Country1 19 0 8 19 13
# Country2 0 19 10 9 10
# Country3 8 10 18 8 18
# Country4 19 9 8 28 13
# Country5 13 10 18 13 23
Hinweis: Sie könnten sogar data = np.einsum('ij,ik,i->jk',m,m,df['Numeric'].to_numpy())
die Multiplikation mit der numerischen Spalte und die Summe über die letzte Achse direkt einschließen.
BEARBEITEN: Hier ist eine Möglichkeit, combinations_with_replacement
die möglicherweise einfacher zu verstehen ist, was passiert (aber die ursprüngliche Antwort mit einsum
führt die gleiche Art von Operationen aus).
from itertools import combinations_with_replacement
#split mask and values
m = df.drop(['Numeric'], axis=1).eq('Yes')
arr = df['Numeric'].to_numpy()
# create result dataframe
res = pd.DataFrame(data=0, index=m.columns, columns=m.columns)
# fill each cell
for colA, colB in combinations_with_replacement(m.columns, 2):
res.loc[colA, colB] = res.loc[colB, colA] = ((m[colA]&m[colB])*arr).sum()
print(res)
# same result
Keine Kommentare:
Kommentar veröffentlichen