我有一個數據幀,有很多行。我正在使用自定義函數生成的數據添加一列,如下所示:熊貓,基於列值的唯一子集追加列
import numpy
df['new_column'] = numpy.vectorize(fx)(df['col_a'], df['col_b'])
# takes 180964.377 ms
它工作的很好,我想要做的是加快速度。實際上只有一小組的col_a
和col_b
的獨特組合。許多迭代是多餘的。我在想也許pandas
只會自己弄清楚,但我不認爲是這樣。試想一下:
print len(df.index) #prints 127255
df_unique = df.copy().drop_duplicates(['col_a', 'col_b'])
print len(df_unique.index) #prints 9834
我也相信自己可能加速通過運行這個:
df_unique['new_column'] = numpy.vectorize(fx)(df_unique['col_a'], df_unique['col_b'])
# takes 14611.357 ms
由於存在大量的冗餘數據,我所要做的是更新的大數據幀( df
127255行),但只需要運行fx
函數的最小次數(9834次)。這是因爲col_a
和col_b
的所有重複行。當然這意味着df
中會有多個行的值爲col_a
和col_b
,但是沒有問題,df
的其他列是不同的,並且使每行都是唯一的。
在我創建一個循環的正常迭代以循環遍歷df_unique
數據框並在df
上執行條件更新之前,我想問一下是否有更加「pythonic」乾淨的方式來執行這種更新。非常感謝。
**更新**
我創建的簡單的上述循環,就像這樣:
df = ...
df_unique = df.copy().drop_duplicates(['col_a', 'col_b'])
df_unique['new_column'] = np.vectorize(fx)(df_unique['col_a'], df_unique['col_b'])
for index, row in df_unique.iterrows():
df.loc[(df['col_a'] == row['col_a']) & (df['col_b'] == row['col_b']),'new_column'] = row['new_column']
# takes 165971.890
這個for循環
所以可能會有輕微的性能增加,但幾乎沒有什麼,我會有預料。
FYI
這是fx
功能。它查詢一個mysql數據庫。
def fx(d):
exp_date = datetime.strptime(d.col_a, '%m/%d/%Y')
if exp_date.weekday() == 5:
exp_date -= timedelta(days=1)
p = pandas.read_sql("select stat from table where a = '%s' and b_date = '%s';" % (d.col_a,exp_date.strftime('%Y-%m-%d')),engine)
if len(p.index) == 0:
return None
else:
return p.iloc[0].close
'col_a','col_b'中有什麼樣的數據?他們已經排序了嗎? – ptrj
它們都是字符串,但col_b是日期字符串。相當肯定他們是排序的。他們似乎是。 –