動機
我經常回答一些問題,我主張將數據幀值轉換爲底層numpy數組以便快速計算。但是,這樣做有一些注意事項,並且有些方法比其他方式更好。如何從數據框中爲列的子集高效地獲取numpy數組?
我會提供自己的答案,努力回饋社區。我希望你們覺得它有用。
問題
考慮數據框df
df = pd.DataFrame(dict(A=[1, 2, 3], B=list('xyz'), C=[9, 8, 7], D=[4, 5, 6]))
print(df)
A B C D
0 1 x 9 4
1 2 y 8 5
2 3 z 7 6
與dtypes
print(df.dtypes)
A int64
B object
C int64
D int64
dtype: object
我想創建一個numpy的陣列a
是由來自列A
和C
的價值觀。假設可能有許多列和我瞄準的兩個特定的列A
和C
我已經試過
我可以這樣做:
df[['A', 'C']].values
array([[1, 9],
[2, 8],
[3, 7]])
這是正確的!
不過,我可以用numpy的
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p]
array([[1, 9],
[2, 8],
[3, 7]], dtype=object)
這是更快,但不準確的做到這一點更快。請注意0。我需要整數!
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p].astype(int)
array([[1, 9],
[2, 8],
[3, 7]])
這現在是正確的,但我可能不知道我有所有整數。
時序
# Clear and accurate, but slower
%%timeit
df[['A', 'C']].values
1000 loops, best of 3: 347 µs per loop
# Not accurate, but close and fast
%%timeit
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p]
10000 loops, best of 3: 59.2 µs per loop
# Accurate for this test case and fast, needs to be more generalized.
%%timeit
p = [df.columns.get_loc(i) for i in ['A', 'C']]
df.values[:, p].astype(int)
10000 loops, best of 3: 59.3 µs per loop
pd系列是否使用numpy數組來存儲其值? – hpaulj
非常有用!我需要爲此加書籤。 – Windchill
@hpaulj我會說實話,我不能確定。但我很確定這是一個肯定的答案。 [**'@屬性; def values' **](https://github.com/pandas-dev/pandas/blob/42e2a87f2a8848795238de1259a3daa5612e393d/pandas/core/series.py#L351)引用了我無法追蹤的'_data'屬性。但是[**'def __init__' **](https://github.com/pandas-dev/pandas/blob/42e2a87f2a8848795238de1259a3daa5612e393d/pandas/core/series.py#L139)顯示'data'屬性被分配了一個[**'SingleBlockManager **](https://github.com/pandas-dev/pandas/blob/42e2a87f2a8848795238de1259a3daa5612e393d/pandas/core/internals.py#L4070) – piRSquared