我想询问一个数据清理问题,我认为python可能更有效。数据有很多错误的列,我必须使用基于某些列的某些特性将它们放在正确的位置。以下是Stata代码中的示例:
forvalues i = 20(-1)2{
local j = `i' + 25
local k = `j' - 2
replace v`j' = v`k' if substr(v23, 1, 4) == "1980"
}
也就是说,如果v25 - v43
列中的观察以“1980”开头,我将列v23
中的内容向后移动2。否则,列是正确的。
感谢任何帮助。
答案 0 :(得分:1)
以下是一个简单示例,表明它有效:
In [65]:
# create some dummy data
import pandas as pd
import io
pd.set_option('display.notebook_repr_html', False)
temp = """v21 v22 v23 v24 v25 v28
1 1 19801923 1 5 8
1 1 20003 1 5 8
1 1 9129389 1 5 8
1 1 1980 1 5 8
1 1 1923 2 5 8
1 1 9128983 1 5 8"""
df = pd.read_csv(io.StringIO(temp),sep='\s+')
df
Out[65]:
v21 v22 v23 v24 v25 v28
0 1 1 19801923 1 5 8
1 1 1 20003 1 5 8
2 1 1 9129389 1 5 8
3 1 1 1980 1 5 8
4 1 1 1923 2 5 8
5 1 1 9128983 1 5 8
In [68]:
# I have to convert my data to a string in order for this to work, it may not be necessary for you in which case the following commented out line would work for you:
#df.v23.str.startswith('1980')
df.v23.astype(str).str.startswith('1980')
Out[68]:
0 True
1 False
2 False
3 True
4 False
5 False
Name: v23, dtype: bool
In [70]:
# now we can call shift by 2 along the column axis to assign the values back
df.loc[df.v23.astype(str).str.startswith('1980'),['v25','v28']] = df.shift(2,axis=1)
df
Out[70]:
v21 v22 v23 v24 v25 v28
0 1 1 19801923 1 19801923 1
1 1 1 20003 1 5 8
2 1 1 9129389 1 5 8
3 1 1 1980 1 1980 1
4 1 1 1923 2 5 8
5 1 1 9128983 1 5 8
所以你需要做的是预先定义列列表:
In [72]:
target_cols = ['v' + str(x) for x in range(25,44)]
print(target_cols)
['v25', 'v26', 'v27', 'v28', 'v29', 'v30', 'v31', 'v32', 'v33', 'v34', 'v35', 'v36', 'v37', 'v38', 'v39', 'v40', 'v41', 'v42', 'v43']
现在将其替换回我的方法,我相信它应该有效:
df.loc[df.v23.astype(str).str.startswith('1980'),target_cols] = df.shift(2,axis=1)
请参阅shift
以了解参数