#python-2.7 #pandas #multidimensional-array
#python-2.7 #pandas #многомерный массив
Вопрос:
У меня довольно большой numpy.ndarray
. Это в основном массив массивов. Я хочу преобразовать его в pandas.DataFrame
. То, что я хочу сделать, находится в приведенном ниже коде
from pandas import DataFrame
cache1 = DataFrame([{'id1': 'ABC1234'}, {'id1': 'NCMN7838'}])
cache2 = DataFrame([{'id2': 3276827}, {'id2': 98567498}, {'id2': 38472837}])
ndarr = [[4.3, 5.6, 6.7], [3.2, 4.5, 2.1]]
arr = []
for idx, i in enumerate(ndarr):
id1 = cache1.ix[idx].id1
for idx2, val in enumerate(i):
id2 = cache2.ix[idx2].id2
if val > 0:
arr.append(dict(id1=id1, id2=id2, value=val))
df = DataFrame(arr)
print(df.head())
Я сопоставляю индекс внешнего массива и внутреннего массива с индексом из двух DataFrame
s, чтобы получить определенные идентификаторы.
cache1
и cache2
есть pandas.DataFrame
. У каждого есть ~100k
строки.
Это занимает действительно много времени, например, несколько часов. Есть ли какой-нибудь способ ускорить это?
Комментарии:
1. Я скопировал код как есть.
cache1['A']
это была внутренняя вещь (в основном ключ к кэшу), поэтому, возможно, это сбивало с толку. Я исправил это сейчас.2. Последняя запись в
cache2
, не должна ли она быть{'id2': 38472837}
вместо{'id': 38472837}
?3. @CTZhu: вы почти наверняка правы.
4. @DSM, в этом случае, возможно
multiindex
, это будет подходящий подход, давайте посмотрим, что говорит OP.
Ответ №1:
Я подозреваю, что ваш ndarr
, если он выражен как 2d np.array
, всегда имеет форму n,m
, где n
— длина cache1.id1
и m
— длина cache2.id2
. И последняя запись в cache2 должна быть {'id2': 38472837}
вместо {'id': 38472837}
. Если это так, то следующее простое решение может быть всем, что нужно:
In [30]:
df=pd.DataFrame(np.array(ndarr).ravel(),
index=pd.MultiIndex.from_product([cache1.id1.values, cache2.id2.values],names=['idx1', 'idx2']),
columns=['val'])
In [33]:
print df.reset_index()
idx1 idx2 val
0 ABC1234 3276827 4.3
1 ABC1234 98567498 5.6
2 ABC1234 38472837 6.7
3 NCMN7838 3276827 3.2
4 NCMN7838 98567498 4.5
5 NCMN7838 38472837 2.1
[6 rows x 3 columns]
На самом деле, я также думаю, что сохранить его MultiIndex
, возможно, будет лучшей идеей.
Ответ №2:
Что-то вроде этого должно работать:
ndarr = np.asarray(ndarr) # if ndarr is actually an array, skip this
fast_df = pd.DataFrame({"value": ndarr.ravel()})
i1, i2 = [i.ravel() for i in np.indices(ndarr.shape)]
fast_df["id1"] = cache1["id1"].loc[i1].values
fast_df["id2"] = cache2["id2"].loc[i2].values
что дает
>>> fast_df
value id1 id2
0 4.3 ABC1234 3276827
1 5.6 ABC1234 98567498
2 6.7 ABC1234 NaN
3 3.2 NCMN7838 3276827
4 4.5 NCMN7838 98567498
5 2.1 NCMN7838 NaN
И затем, если вы действительно хотите удалить нулевые значения, вы можете использовать только ненулевые fast_df = fast_df[fast_df['value'] != 0]
.