如何对数据框的行应用操作,但影响可变列?
How to apply operations on rows of a dataframe, but with variable columns affected?
我有一个从 csv 读取的数据框,其中包含无关数据。
通过评估一列 SystemStart 来判断什么是无关的。
标题日期值低于该行的 SystemStart 的列中每行的任何数据都设置为 nan。例如,index = 'one' 的 SystemStart 日期为“2016-1-5”,并且在设置 pd.date_range 时,它没有要填充的 nan 值。 index= 'three' 是 '2016-1-7' 因此有两个 nan 值替换原始数据。
我可以去 row-by-row 并在所有列上抛出 np.nan 值,但速度很慢。有没有更快的方法?
我在下面创建了一个有代表性的数据框,我希望在没有迭代操作的情况下获得相同的结果,或者寻找一种加速这些操作的方法。任何帮助将不胜感激。
import pandas as pd
import numpy as np
start_date = '2016-1-05'
end_date = '2016-1-7'
dates = pd.date_range(start_date, end_date, freq='D')
dt_dates = pd.to_datetime(dates, unit='D')
ind = ['one', 'two', 'three']
df = pd.DataFrame(np.random.randint(0,100,size=(3, 3)), columns = dt_dates, index = ind)
df['SystemStart'] = pd.to_datetime(['2016-1-5', '2016-1-6', '2016-1-7'])
print 'Initial Dataframe: \n', df
for msn in df.index:
zero_date_range = pd.date_range(start_date, df.loc[msn,'SystemStart'] - pd.Timedelta(days=1), freq='D')
# we set zeroes for all columns in the index element in question - this is a horribly slow way to do this
df.loc[msn, zero_date_range] = np.NaN
print '\nAltered Dataframe: \n', df
下面是 df 输出,初始的和改变的:
Initial Dataframe:
2016-01-05 00:00:00 2016-01-06 00:00:00 2016-01-07 00:00:00 \
one 24 23 65
two 21 91 59
three 62 77 2
SystemStart
one 2016-01-05
two 2016-01-06
three 2016-01-07
Altered Dataframe:
2016-01-05 00:00:00 2016-01-06 00:00:00 2016-01-07 00:00:00 \
one 24.0 23.0 65
two NaN 91.0 59
three NaN NaN 2
SystemStart
one 2016-01-05
two 2016-01-06
three 2016-01-07
我做的第一件事是确保 SystemStart
是 datetime
df.SystemStart = pd.to_datetime(df.SystemStart)
然后我将 SystemStart
剥离到一个单独的系列中
st = df.SystemStart
然后我从 df
中删除 SytstemStart
d1 = df.drop('SystemStart', 1)
然后我将剩下的列转换为 datetime
d1.columns = pd.to_datetime(d1.columns)
最后我使用 numpy
广播来屏蔽适当的单元格并加入 SystemStart
回来。
d1.where(d1.columns.values >= st.values[:, None]).join(st)
我有一个从 csv 读取的数据框,其中包含无关数据。 通过评估一列 SystemStart 来判断什么是无关的。 标题日期值低于该行的 SystemStart 的列中每行的任何数据都设置为 nan。例如,index = 'one' 的 SystemStart 日期为“2016-1-5”,并且在设置 pd.date_range 时,它没有要填充的 nan 值。 index= 'three' 是 '2016-1-7' 因此有两个 nan 值替换原始数据。
我可以去 row-by-row 并在所有列上抛出 np.nan 值,但速度很慢。有没有更快的方法?
我在下面创建了一个有代表性的数据框,我希望在没有迭代操作的情况下获得相同的结果,或者寻找一种加速这些操作的方法。任何帮助将不胜感激。
import pandas as pd
import numpy as np
start_date = '2016-1-05'
end_date = '2016-1-7'
dates = pd.date_range(start_date, end_date, freq='D')
dt_dates = pd.to_datetime(dates, unit='D')
ind = ['one', 'two', 'three']
df = pd.DataFrame(np.random.randint(0,100,size=(3, 3)), columns = dt_dates, index = ind)
df['SystemStart'] = pd.to_datetime(['2016-1-5', '2016-1-6', '2016-1-7'])
print 'Initial Dataframe: \n', df
for msn in df.index:
zero_date_range = pd.date_range(start_date, df.loc[msn,'SystemStart'] - pd.Timedelta(days=1), freq='D')
# we set zeroes for all columns in the index element in question - this is a horribly slow way to do this
df.loc[msn, zero_date_range] = np.NaN
print '\nAltered Dataframe: \n', df
下面是 df 输出,初始的和改变的:
Initial Dataframe:
2016-01-05 00:00:00 2016-01-06 00:00:00 2016-01-07 00:00:00 \
one 24 23 65
two 21 91 59
three 62 77 2
SystemStart
one 2016-01-05
two 2016-01-06
three 2016-01-07
Altered Dataframe:
2016-01-05 00:00:00 2016-01-06 00:00:00 2016-01-07 00:00:00 \
one 24.0 23.0 65
two NaN 91.0 59
three NaN NaN 2
SystemStart
one 2016-01-05
two 2016-01-06
three 2016-01-07
我做的第一件事是确保 SystemStart
是 datetime
df.SystemStart = pd.to_datetime(df.SystemStart)
然后我将 SystemStart
剥离到一个单独的系列中
st = df.SystemStart
然后我从 df
SytstemStart
d1 = df.drop('SystemStart', 1)
然后我将剩下的列转换为 datetime
d1.columns = pd.to_datetime(d1.columns)
最后我使用 numpy
广播来屏蔽适当的单元格并加入 SystemStart
回来。
d1.where(d1.columns.values >= st.values[:, None]).join(st)