在 Pandas 中系统地 heading-to-value 数据清理
Systematic heading-to-value data cleaning in Pandas
我有一个非常广泛的数据集,它包含数百个 date-value 列对 - 但是值列的标题包含从中获取数据的站点的引用。在将此数据转换为长格式之前,我想将此 header 作为新的“site_name”列。
每个站点的数据都是相同的 2 列格式,因此我希望能够一次对整个数据集应用一个解决方案。
我下面的代码说明了单个 date-value 对
的问题
注意:我使用星号表示我是在描述列名,而不是引用它们
import pandas as pd
current = pd.DataFrame({"*unnamed_date_column*" : ["2021-10-21", "2021-10-22", "2021-10-23"],
"*unique_site_name*" : [1.1, 1.2, 1.3]})
desired = pd.DataFrame({"date" : ["2021-10-21", "2021-10-22", "2021-10-23"],
"values" : [1.1, 1.2, 1.3],
"site" : ["unique_site_name", "unique_site_name", "unique_site_name"]})
在不了解更多示例的情况下很难知道这将如何概括,但您可以尝试:
desired = (current
.assign(site=current.columns[-1]) # arbitrarily chose to index from end
.rename(columns=dict(zip(current.columns, ['date', 'values'])))
)
输出:
date values site
0 2021-10-21 1.1 *unique_site_name*
1 2021-10-22 1.2 *unique_site_name*
2 2021-10-23 1.3 *unique_site_name*
你可以使用 melt :
desired = current.melt(id_vars=["*unnamed_date_column*"],var_name=['site']).rename(columns ={"*unnamed_date_column*": "date"})
输出:
date site value
0 2021-10-21 *unique_site_name* 1.1
1 2021-10-22 *unique_site_name* 1.2
2 2021-10-23 *unique_site_name* 1.3
已解决:
几乎肯定不是执行此操作的最佳方法,但适用于我的 200 列数据框:
- 提取所有列的名称
- 使用以下方法将它们分成 2 组
np.array_split()
- 迭代此 date-value 对列表,
应用 assign/rename-with-dictionary 求解提取数据
通过@mozway
- 将更改后的数据帧保存到新字典中,然后
连接
colnames = np.array_split(list(current.columns), len(list(current.columns)) / 2)
reorg = {}
for i in range(0, length):
df = current[colnames[i]]
rename_ind = [0, 1]
old_names = df.columns[rename_ind]
new_names = ['date', 'value']
new_df = df.assign(site = df.columns[1])
new_df.rename(columns = dict(zip(old_names, new_names)), inplace = True)
reorg[i] = new_df
pd.concat(reorg.values())
我有一个非常广泛的数据集,它包含数百个 date-value 列对 - 但是值列的标题包含从中获取数据的站点的引用。在将此数据转换为长格式之前,我想将此 header 作为新的“site_name”列。
每个站点的数据都是相同的 2 列格式,因此我希望能够一次对整个数据集应用一个解决方案。
我下面的代码说明了单个 date-value 对
的问题注意:我使用星号表示我是在描述列名,而不是引用它们
import pandas as pd
current = pd.DataFrame({"*unnamed_date_column*" : ["2021-10-21", "2021-10-22", "2021-10-23"],
"*unique_site_name*" : [1.1, 1.2, 1.3]})
desired = pd.DataFrame({"date" : ["2021-10-21", "2021-10-22", "2021-10-23"],
"values" : [1.1, 1.2, 1.3],
"site" : ["unique_site_name", "unique_site_name", "unique_site_name"]})
在不了解更多示例的情况下很难知道这将如何概括,但您可以尝试:
desired = (current
.assign(site=current.columns[-1]) # arbitrarily chose to index from end
.rename(columns=dict(zip(current.columns, ['date', 'values'])))
)
输出:
date values site
0 2021-10-21 1.1 *unique_site_name*
1 2021-10-22 1.2 *unique_site_name*
2 2021-10-23 1.3 *unique_site_name*
你可以使用 melt :
desired = current.melt(id_vars=["*unnamed_date_column*"],var_name=['site']).rename(columns ={"*unnamed_date_column*": "date"})
输出:
date site value
0 2021-10-21 *unique_site_name* 1.1
1 2021-10-22 *unique_site_name* 1.2
2 2021-10-23 *unique_site_name* 1.3
已解决:
几乎肯定不是执行此操作的最佳方法,但适用于我的 200 列数据框:
- 提取所有列的名称
- 使用以下方法将它们分成 2 组 np.array_split()
- 迭代此 date-value 对列表, 应用 assign/rename-with-dictionary 求解提取数据 通过@mozway
- 将更改后的数据帧保存到新字典中,然后 连接
colnames = np.array_split(list(current.columns), len(list(current.columns)) / 2)
reorg = {}
for i in range(0, length):
df = current[colnames[i]]
rename_ind = [0, 1]
old_names = df.columns[rename_ind]
new_names = ['date', 'value']
new_df = df.assign(site = df.columns[1])
new_df.rename(columns = dict(zip(old_names, new_names)), inplace = True)
reorg[i] = new_df
pd.concat(reorg.values())