更改pandas中列名的一部分?

时间:2016-03-31 20:03:07

标签: python pandas

我有一个列列表,我想根据值列表重命名一部分。

我正在查看一个包含12个月数据的文件,每个月都是不同的列(我不幸地需要保留这种特定格式)。这个文件每个月生成一次,我保持列名更加通用,因为我必须根据月份数对它们进行大量计算(例如,我需要将信息与第8,9和10个月的平均值进行比较)每个月)。

以下是我要重命名的列:

['month_1_Sign',
 'month_2_Sign',
 'month_3_Sign',
 'month_4_Sign',
 'month_5_Sign',
 'month_6_Sign',
 'month_7_Sign',
 'month_8_Sign',
 'month_9_Sign',
 'month_10_Sign',
 'month_11_Sign',
 'month_12_Sign',
 'month_1_Actual',
 'month_2_Actual',
 'month_3_Actual',
 'month_4_Actual',
 'month_5_Actual',
 'month_6_Actual',
 'month_7_Actual',
 'month_8_Actual',
 'month_9_Actual',
 'month_10_Actual',
 'month_11_Actual',
 'month_12_Actual',
 'month_1_Target',
 'month_2_Target',
 'month_3_Target',
 'month_4_Target',
 'month_5_Target',
 'month_6_Target',
 'month_7_Target',
 'month_8_Target',
 'month_9_Target',
 'month_10_Target',
 'month_11_Target',
 'month_12_Target']

以下是我要放置的名称:

required_date_range = sorted(list(pd.Series(pd.date_range((dt.datetime.today().date() + pd.DateOffset(months=-13)), periods=12, freq='MS')).dt.strftime('%Y-%m-%d')))

['2015-03-01',
 '2015-04-01',
 '2015-05-01',
 '2015-06-01',
 '2015-07-01',
 '2015-08-01',
 '2015-09-01',
 '2015-10-01',
 '2015-11-01',
 '2015-12-01',
 '2016-01-01',
 '2016-02-01']

因此,month_12列(month_12始终是最近一个月)将更改为' 2016-02-01_Sign',' 2016-02-01_Actual',' 2016- 02-01_Target'在这个例子中。

我试过这样做,但它没有改变任何东西(尝试用它所指的实际日期来改变月份#):

final.replace('month_10', required_date_range[9], inplace=True)
final.replace('month_11', required_date_range[10], inplace=True)
final.replace('month_12', required_date_range[11], inplace=True)
final.replace('month_1', required_date_range[0], inplace=True)
final.replace('month_2', required_date_range[1], inplace=True)
final.replace('month_3', required_date_range[2], inplace=True)
final.replace('month_4', required_date_range[3], inplace=True)
final.replace('month_5', required_date_range[4], inplace=True)
final.replace('month_6', required_date_range[5], inplace=True)
final.replace('month_7', required_date_range[6], inplace=True)
final.replace('month_8', required_date_range[7], inplace=True)
final.replace('month_9', required_date_range[8], inplace=True)

3 个答案:

答案 0 :(得分:1)

from collections import product

df = pd.DataFrame(np.random.rand(3, 12 * 3), columns=['month_' + str(c[0]) + '_' + c[1] for c in product(range(1, 13), ['Sign', 'Actual', 'Target'])])

首先创建相关月份的映射。

mapping = {'month_' + str(n): date for n, date in enumerate(required_date_range, 1)}

>>> mapping
{'month_1': '2015-03-01',
 'month_10': '2015-12-01',
 'month_11': '2016-01-01',
 'month_12': '2016-02-01',
 'month_2': '2015-04-01',
 'month_3': '2015-05-01',
 'month_4': '2015-06-01',
 'month_5': '2015-07-01',
 'month_6': '2015-08-01',
 'month_7': '2015-09-01',
 'month_8': '2015-10-01',
 'month_9': '2015-11-01'}

然后重新分配列,将映射的月份(例如' 2016-02-01')加入到列名的其余部分。这是使用列表理解完成的。

df.columns = [mapping.get(c[:c.find('_', 6)]) + c[c.find('_', 6):] for c in cols]

>>> df.columns.tolist()
['2015-03-01_Sign',
 '2015-04-01_Sign',
 '2015-05-01_Sign',
 '2015-06-01_Sign',
 '2015-07-01_Sign',
 '2015-08-01_Sign',
 '2015-09-01_Sign',
 '2015-10-01_Sign',
 '2015-11-01_Sign',
 '2015-12-01_Sign',
 '2016-01-01_Sign',
 '2016-02-01_Sign',
 '2015-03-01_Actual',
 '2015-04-01_Actual',
 '2015-05-01_Actual',
 '2015-06-01_Actual',
 '2015-07-01_Actual',
 '2015-08-01_Actual',
 '2015-09-01_Actual',
 '2015-10-01_Actual',
 '2015-11-01_Actual',
 '2015-12-01_Actual',
 '2016-01-01_Actual',
 '2016-02-01_Actual',
 '2015-03-01_Target',
 '2015-04-01_Target',
 '2015-05-01_Target',
 '2015-06-01_Target',
 '2015-07-01_Target',
 '2015-08-01_Target',
 '2015-09-01_Target',
 '2015-10-01_Target',
 '2015-11-01_Target',
 '2015-12-01_Target',
 '2016-01-01_Target',
 '2016-02-01_Target']

答案 1 :(得分:1)

你可以构造一个dict然后在拆分列str上调用map

In [27]:
d = dict(zip([str(x) for x in range(1,13)], required_date_range))
d

Out[27]:
{'1': '2015-03-01',
 '10': '2015-12-01',
 '11': '2016-01-01',
 '12': '2016-02-01',
 '2': '2015-04-01',
 '3': '2015-05-01',
 '4': '2015-06-01',
 '5': '2015-07-01',
 '6': '2015-08-01',
 '7': '2015-09-01',
 '8': '2015-10-01',
 '9': '2015-11-01'}

In [26]:
df.columns = df.columns.to_series().str.rsplit('_').str[1].map(d) + '_' + df.columns.to_series().str.rsplit('_').str[-1]
df.columns

Out[26]:
Index(['2015-03-01_Sign', '2015-04-01_Sign', '2015-05-01_Sign',
       '2015-06-01_Sign', '2015-07-01_Sign', '2015-08-01_Sign',
       '2015-09-01_Sign', '2015-10-01_Sign', '2015-11-01_Sign',
       '2015-12-01_Sign', '2016-01-01_Sign', '2016-02-01_Sign',
       '2015-03-01_Actual', '2015-04-01_Actual', '2015-05-01_Actual',
       '2015-06-01_Actual', '2015-07-01_Actual', '2015-08-01_Actual',
       '2015-09-01_Actual', '2015-10-01_Actual', '2015-11-01_Actual',
       '2015-12-01_Actual', '2016-01-01_Actual', '2016-02-01_Actual',
       '2015-03-01_Target', '2015-04-01_Target', '2015-05-01_Target',
       '2015-06-01_Target', '2015-07-01_Target', '2015-08-01_Target',
       '2015-09-01_Target', '2015-10-01_Target', '2015-11-01_Target',
       '2015-12-01_Target', '2016-01-01_Target', '2016-02-01_Target'],
      dtype='object')

答案 2 :(得分:1)

您将要使用.rename方法而不是.replace!例如这段代码:

malloc

更改' a'和' b'列标题为' x1'和' x2'分别

您重命名代码的第一行将更改为:

import pandas as pd

d = {'a': [1, 2, 4], 'b':[2,3,4],'c':[3,4,5]}
df = pd.DataFrame(d)
df.rename(columns={'a': 'x1', 'b': 'x2'}, inplace=True)

实际上,您可以通过向columns字典参数添加条目来执行该命令中的每一列。

final.rename(columns={'month_10':required_date_range[9]}, inplace=True)