Betrachten Sie die pd.DataFrame
und pd.Series
, A
und B
A = pd.DataFrame([
[28, 39, 52],
[77, 80, 66],
[7, 18, 24],
[9, 97, 68]
])
B = pd.Series([32, 5, 42, 17])
pandas
standardmäßig, wenn Sie eine pd.DataFrame
mit pd.Series
, Pandas ausrichtet vergleichen jeder Indexwert aus der Reihe mit den Spaltennamen des Datenrahmens. Dies passiert, wenn Sie A < B
verwenden. In diesem Fall haben Sie 4 Zeilen in Ihrem Datenframe und 4 Elemente in Ihrer Serie, also gehe ich davon aus, dass Sie die Indexwerte der Serie an die Indexwerte des Datenrahmens anpassen wollen. Um die Achse anzugeben, an der Sie ausrichten möchten, müssen Sie die Vergleichsmethode und nicht den Operator verwenden. Wenn Sie die Methode verwenden, können Sie den axis
-Parameter verwenden und angeben, dass Sie lieber axis=0
als den Standard axis=1
möchten.
A.lt(B, axis=0)
0 1 2
0 True False False
1 False False False
2 True True True
3 True False False
ich oft nur schreiben dies als A.lt(B, 0)
numpy
In numpy, man muss auch die Aufmerksamkeit auf die Dimensionalität der Arrays zahlen und Sie davon aus, dass Die Positionen sind bereits aufgereiht. Die Positionen werden berücksichtigt, wenn sie aus demselben Datenrahmen stammen.
print(A.values)
[[28 39 52]
[77 80 66]
[ 7 18 24]
[ 9 97 68]]
print(B.values)
[32 5 42 17]
Hinweis, dass B
ist ein 1-dimensionales Array, während A ein 2-dimensionales Array ist. Um B
entlang der Zeilen von A
zu vergleichen, müssen wir B
in ein zweidimensionales Array umformen. Der offensichtlichste Weg, dies zu tun, ist mit reshape
print(A.values < B.values.reshape(4, 1))
[[ True False False]
[False False False]
[ True True True]
[ True False False]]
Diese sind jedoch Möglichkeiten, in denen Sie häufig andere sehen das gleiche tun
A.values < B.values.reshape(-1, 1)
Oder
A.values < B.values[:, None]
Umformung
zeitgesteuerter Test
Um zu verstehen, wie schnell diese Vergleiche sind, habe ich den folgenden Backtest konstruiert.
def pd_cmp(df, s):
return df.lt(s, 0)
def np_cmp_a2a(df, s):
"""To get an apples to apples comparison
I return the same thing in both functions"""
return pd.DataFrame(
df.values < s.values[:, None],
df.index, df.columns
)
def np_cmp_a2o(df, s):
"""To get an apples to oranges comparison
I return a numpy array"""
return df.values < s.values[:, None]
results = pd.DataFrame(
index=pd.Index([10, 1000, 100000], name='group size'),
columns=pd.Index(['pd_cmp', 'np_cmp_a2a', 'np_cmp_a2o'], name='method'),
)
from timeit import timeit
for i in results.index:
df = pd.concat([A] * i, ignore_index=True)
s = pd.concat([B] * i, ignore_index=True)
for j in results.columns:
results.set_value(
i, j,
timeit(
'{}(df, s)'.format(j),
'from __main__ import {}, df, s'.format(j),
number=100
)
)
results.plot()
ich, dass die schnellen numpy
basierten Lösungen schließen kann, aber alles, was nicht viel. Sie alle skalieren gleich.
Da OP sagt, dass die Arrays sehr groß sind, würde Leistungsvergleich b/w Pandas vs Numpy für zukünftige Leser sehr informativ sein – kmario23
@ kmario23 Ich habe meinen Beitrag mit Timings – piRSquared
aktualisiert Ich mag wirklich Ihre Pandas "Zeit" Wrapper. – MaxU