【发布时间】:2017-11-17 23:11:35
【问题描述】:
背景
我想识别数据框中与字符串部分匹配的列名,并将它们替换为原始名称以及添加到其中的一些新元素。新元素是由列表定义的整数。这是similar question,但恐怕建议的解决方案在我的特定情况下不够灵活。 here 是另一个帖子,其中包含一些与我面临的问题非常接近的优秀答案。
一些研究
我知道我可以组合两个字符串列表,将它们成对映射 into a dictionary 和 rename the columns,使用字典作为函数 df.rename 中的输入。但是考虑到现有列的数量会有所不同,这似乎有点太复杂了,而且不是很灵活。重命名的列数也是如此。
下面的 sn-p 将产生一个输入示例:
# Libraries
import numpy as np
import pandas as pd
import itertools
# A dataframe
Observations = 5
Columns = 5
np.random.seed(123)
df = pd.DataFrame(np.random.randint(90,110,size=(Observations, Columns)),
columns = ['Price','obs_1','obs_2','obs_3','obs_4'])
datelist = pd.date_range(pd.datetime.today().strftime('%Y-%m-%d'),
periods=Observations).tolist()
df['Dates'] = datelist
df = df.set_index(['Dates'])
print(df)
输入
我想识别以obs_ 开头的列名,并在= 符号后添加newElements = [5, 10, 15, 20] 列表中的元素(整数)。名为 Price 的列保持不变。 obs_ 列之后出现的其他列也应该保持不变。
以下 sn-p 将演示所需的输出:
# Desired output
Observations = 5
Columns = 5
np.random.seed(123)
df2 = pd.DataFrame(np.random.randint(90,110,size=(Observations, Columns)),
columns = ['Price','Obs_1 = 5','Obs_2 = 10','Obs_3 = 15','Obs_4 = 20'])
df2['Dates'] = datelist
df2 = df2.set_index(['Dates'])
print(df2)
输出
我的尝试
# Define the partial string I'm lookin for
stringMatch = 'Obs_'
# Put existing column names in a list
oldnames = list(df)
# Put elements that should be added to the column names
# where the three first letters match 'obs_'
newElements = [5, 10, 15, 20]
oldElements = [1, 2, 3, 4]
# Change types of the elements in the list
str_newElements = [str(x) for x in newElements]
str_oldElements = [str(y) for y in oldElements]
str_newNames = str_newElements.copy()
# Since I know the first column should not be renamed,
# I start with 'Price' in a list
newnames = ['Price']
# Then I add the renamed parts to the same list
i = 0
for oldElement in str_oldElements:
#print(repr(oldElement) + repr(str_newElements[i]))
newnames.append(stringMatch + oldElement + ' = ' + str_newElements[i])
i = i + 1
# Rename columns using the dict as input in df.rename
df.rename(columns = dict(zip(oldnames, newnames)), inplace = True)
print('My attempt: ', df)
已经制作了新列名的完整列表
我也可以使用df.columns = newnames,
但希望你们中的一个人有使用的建议
df.rename 以更 Python 的方式。
感谢您的任何建议!
这是一个简单的复制粘贴的完整代码:
# Libraries
import numpy as np
import pandas as pd
import itertools
# A dataframe
Observations = 5
Columns = 5
np.random.seed(123)
df = pd.DataFrame(np.random.randint(90,110,size=(Observations, Columns)),
columns = ['Price','obs_1','obs_2','obs_3','obs_4'])
datelist = pd.date_range(pd.datetime.today().strftime('%Y-%m-%d'),
periods=Observations).tolist()
df['Dates'] = datelist
df = df.set_index(['Dates'])
print('Input: ', df)
# Desired output
Observations = 5
Columns = 5
np.random.seed(123)
df2 = pd.DataFrame(np.random.randint(90,110,size=(Observations, Columns)),
columns = ['Price','Obs_1 = 5','Obs_2 = 10','Obs_3 = 15','Obs_4 = 20'])
df2['Dates'] = datelist
df2 = df2.set_index(['Dates'])
print('Desired output: ', df2)
# My attempts
# Define the partial string I'm lookin for
stringMatch = 'Obs_'
# Put existing column names in a list
oldnames = list(df)
# Put elements that should be added to the column names
# where the three first letters match 'obs_'
newElements = [5, 10, 15, 20]
oldElements = [1, 2, 3, 4]
# Change types of the elements in the list
str_newElements = [str(x) for x in newElements]
str_oldElements = [str(y) for y in oldElements]
str_newNames = str_newElements.copy()
# Since I know the first column should not be renamed,
# I start with 'Price' in a list
newnames = ['Price']
# Then I add the renamed parts to the same list
i = 0
for oldElement in str_oldElements:
#print(repr(oldElement) + repr(str_newElements[i]))
newnames.append(stringMatch + oldElement + ' = ' + str_newElements[i])
i = i + 1
# Rename columns using the dict as input in df.rename
df.rename(columns = dict(zip(oldnames, newnames)), inplace = True)
print('My attempt: ', df)
编辑:后果
仅仅一天之后就有这么多好的答案真是太棒了!这使得很难决定接受哪个答案。我不知道以下内容是否会为整个帖子增加很多价值,但我继续将所有建议包装到函数中并使用 %timeit 对其进行测试。
建议框架 HH1 是第一个发布的,也是执行时间最快的框架之一。如果有人感兴趣,我稍后会包含代码。
编辑 2
sn-p 工作正常,直到最后一行。运行df = df.rename(columns=dict(zip(names,renames))) 行后,数据框如下所示:
【问题讨论】:
标签: python python-3.x pandas dictionary dataframe