我有一个嵌套的for循环,我想知道是否有更有效的方法来实现此目的,即代码方式:
我的数据类似于以下内容。
ID | DEAD | 2009-10 | ... | 2016-10
-----------------------------------------
1 | 2018-11 | 5.4 | ... | 6.5
2 | 2014-01 | 0.5 | ... | 5.2
...
N | 2008-11 | 8.6 | ... | 1.3
目标是在产品到期后(“ DEAD”列<日期)时立即用np.NaN
替换值,否则值应保持不变。
ID | DEAD | 2009-10 | ... | 2016-10
-----------------------------------------
1 | 2018-11 | 5.4 | ... | 6.5
2 | 2014-01 | 0.5 | ... | NaN
...
N | 2008-11 | 8.6 | ... | NaN
我的最初想法是应用嵌套的for循环来检查是否达到条件'DEAD' < date
。该方法适用于较小的N。但是由于我的数据包括20,000行和400列,因此需要太多时间。
time = df.columns[2:] # take the header as an index
time = pd.DataFrame(time)
time.columns = ['Dummy']
time['Dummy'] = pd.to_datetime(time.Dummy) # Convert index argument to datetime
df['DEAD'] = pd.to_datetime(tore.DEAD) # Convert column 'DEAD' to datetime
lists = []
for i in range(397):
row = []
for j in range(20000):
if time.iloc[i,0] <= df.iloc[j,0]:
newlist = df.iloc[j,i]
else:
newlist = np.NaN
row.append(newlist)
lists.append(row)
lists = pd.DataFrame(lists)
lists = lists.transpose()
感谢任何建议!
答案 0 :(得分:4)
您可以尝试遍历每列:
for column_name in df.drop('DEAD', axis=1):
column_date = pd.to_datetime(column_name)
df[column_name].mask(df['DEAD']<column_date, inplace=True)
此处的mask方法也很有用。
答案 1 :(得分:1)
如果列是有序的(例如,按日期升序),则可以避免某些循环和检查。
i
index >= i
将所有后续列更新为NaN
值更新本身仍在逐个单元完成,可能效果不佳。
如果创建第二个数据框,其尺寸可以像位掩码一样使用,并且包含指示是否应保留基础数据框中的值的0
和1
值,则可能会获得更好的性能或删除。
答案 2 :(得分:0)
如果此数据存储在数据库中,则应直接使用sql进行操作,速度要快得多。