重新排列错位的列

时间:2014-08-10 07:04:39

标签: python pandas

我想询问一个数据清理问题,我认为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。否则,列是正确的。

感谢任何帮助。

1 个答案:

答案 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以了解参数