编辑多个列的值并合并为一个列(pandas,python)
我想找个方法,用pandas和python把一个Excel表格里几个已知名字的列合并成一个新的列,同时保留所有重要的信息,下面是个例子:
输入:
ID,tp_c,tp_b,tp_p
0,transportation - cars,transportation - boats,transportation - planes
1,checked,-,-
2,-,checked,-
3,checked,checked,-
4,-,checked,checked
5,checked,checked,checked
想要的输出:
ID,tp_all
0,transportation
1,cars
2,boats
3,cars+boats
4,boats+planes
5,cars+boats+planes
ID为0的那一行包含了列内容的描述。理想情况下,代码会解析第二行的描述,找到'-'后面的内容,并把这些值合并到新的“tp_all”列里。
3 个回答
1
这里有一种方法:
newCol = pandas.Series('',index=d.index)
for col in d.ix[:, 1:]:
name = '+' + col.split('-')[1].strip()
newCol[d[col]=='checked'] += name
newCol = newCol.str.strip('+')
然后:
>>> newCol
0 cars
1 boats
2 cars+boats
3 boats+planes
4 cars+boats+planes
dtype: object
你可以用这个新列创建一个新的数据表,或者随意处理它。
补充说明:我看到你修改了问题,现在交通方式的名称在第0行,而不是在列标题里。如果把它们放在列标题里会更简单(这是我答案的假设),而且你新的列标题似乎没有包含任何额外有用的信息,所以你可能应该先把列名设置为第0行的信息,然后删除第0行。
3
这真有意思,因为它是一个反向的 get_dummies
操作...
我觉得我会手动处理一下列名,这样你就能得到一个布尔值的数据框:
In [11]: df1 # df == 'checked'
Out[11]:
cars boats planes
0
1 True False False
2 False True False
3 True True False
4 False True True
5 True True True
现在你可以用 zip 和 apply 来处理:
In [12]: df1.apply(lambda row: '+'.join([col for col, b in zip(df1.columns, row) if b]),
axis=1)
Out[12]:
0
1 cars
2 boats
3 cars+boats
4 boats+planes
5 cars+boats+planes
dtype: object
接下来你只需要调整一下表头,就能得到想要的 csv 文件。
如果能有一种更简单或更快的方法来反向操作 get_dummies
就好了...
1
好的,这里有一种更灵活的方法:
In [63]:
# get a list of the columns
col_list = list(df.columns)
# remove 'ID' column
col_list.remove('ID')
# create a dict as a lookup
col_dict = dict(zip(col_list, [df.iloc[0][col].split(' - ')[1] for col in col_list]))
col_dict
Out[63]:
{'tp_b': 'boats', 'tp_c': 'cars', 'tp_p': 'planes'}
In [64]:
# define a func that tests the value and uses the dict to create our string
def func(x):
temp = ''
for col in col_list:
if x[col] == 'checked':
if len(temp) == 0:
temp = col_dict[col]
else:
temp = temp + '+' + col_dict[col]
return temp
df['combined'] = df[1:].apply(lambda row: func(row), axis=1)
df
Out[64]:
ID tp_c tp_b tp_p \
0 0 transportation - cars transportation - boats transportation - planes
1 1 checked NaN NaN
2 2 NaN checked NaN
3 3 checked checked NaN
4 4 NaN checked checked
5 5 checked checked checked
combined
0 NaN
1 cars
2 boats
3 cars+boats
4 boats+planes
5 cars+boats+planes
[6 rows x 5 columns]
In [65]:
df = df.ix[1:,['ID', 'combined']]
df
Out[65]:
ID combined
1 1 cars
2 2 boats
3 3 cars+boats
4 4 boats+planes
5 5 cars+boats+planes
[5 rows x 2 columns]