Python 3.x 将列标题转换为新列并保留每列的值
UPD:在页面底部粘贴了一个数据框作为示例 我的原始xls文件如下所示: 我需要两个动作才能让它看起来像下面这样: 首先,我需要用上面单元格中显示的值填充空行值。这已通过以下功能实现:Python 3.x 将列标题转换为新列并保留每列的值,python-3.x,pandas,Python 3.x,Pandas,UPD:在页面底部粘贴了一个数据框作为示例 我的原始xls文件如下所示: 我需要两个动作才能让它看起来像下面这样: 首先,我需要用上面单元格中显示的值填充空行值。这已通过以下功能实现: def get_csv(): #Read csv file df = pd.read_excel('test.xls') df = df.fillna(method='ffill') return df 其次,我使用了stack和set\u index: df = (df.s
def get_csv():
#Read csv file
df = pd.read_excel('test.xls')
df = df.fillna(method='ffill')
return df
其次,我使用了stack
和set\u index
:
df = (df.set_index(['Country', 'Gender', 'Arr-Dep'])
.stack()
.reset_index(name='Value')
.rename(columns={'level_3':'Year'}))
我想知道是否有更简单的方法。是否有将数据框、excel等转换为所需格式的库
excel导入后的原始数据框:
Country Gender Direction 1974 1975 1976
0 Austria Male IN 13728 8754 9695
1 NaN NaN OUT 17977 12271 9899
2 NaN Female IN 8541 6465 6447
3 NaN NaN OUT 8450 7190 6288
4 NaN Total IN 22269 15219 16142
5 NaN NaN OUT 26427 19461 16187
6 Belgium Male IN 2412 2245 2296
7 NaN NaN OUT 2800 2490 2413
8 NaN Female IN 2105 2022 2057
9 NaN NaN OUT 2100 2113 2004
10 NaN Total IN 4517 4267 4353
11 NaN NaN OUT 4900 4603 4417
使用替代解决方案,但如果需要相同的列顺序,如
堆叠
数据帧
,则需要添加:
使用替代解决方案,但如果需要相同的列顺序,如
堆叠
数据帧
,则需要添加:
堆栈
我喜欢你的方法。我会用几种方法来改变它
ffill
努比 我想制定一个定制方法。这应该很快
def cstm_ffill(s):
i = np.flatnonzero(s.notna())
i = np.concatenate([[0], i, [len(s)]])
d = np.diff(i)
a = s.values[i[:-1].repeat(d)]
return a
def cstm_melt(df):
c = cstm_ffill(df.Country)
g = cstm_ffill(df.Gender)
d = cstm_ffill(df.Direction)
y = df.columns[3:].values
k = len(y)
i = np.column_stack([c, g, d])
v = np.column_stack([*map(df.get, y)]).ravel()
df_ = pd.DataFrame(
np.column_stack([i.repeat(k, axis=0), v, np.tile(y, len(i))]),
columns=['Country', 'Gender', 'Direction', 'Year', 'Value']
)
return df_
cstm_melt(df)
Country Gender Direction Year Value
0 Austria Male IN 13728 1974
1 Austria Male IN 8754 1975
2 Austria Male IN 9695 1976
3 Austria Male OUT 17977 1974
4 Austria Male OUT 12271 1975
5 Austria Male OUT 9899 1976
...
堆栈
我喜欢你的方法。我会用几种方法来改变它
ffill
努比 我想制定一个定制方法。这应该很快
def cstm_ffill(s):
i = np.flatnonzero(s.notna())
i = np.concatenate([[0], i, [len(s)]])
d = np.diff(i)
a = s.values[i[:-1].repeat(d)]
return a
def cstm_melt(df):
c = cstm_ffill(df.Country)
g = cstm_ffill(df.Gender)
d = cstm_ffill(df.Direction)
y = df.columns[3:].values
k = len(y)
i = np.column_stack([c, g, d])
v = np.column_stack([*map(df.get, y)]).ravel()
df_ = pd.DataFrame(
np.column_stack([i.repeat(k, axis=0), v, np.tile(y, len(i))]),
columns=['Country', 'Gender', 'Direction', 'Year', 'Value']
)
return df_
cstm_melt(df)
Country Gender Direction Year Value
0 Austria Male IN 13728 1974
1 Austria Male IN 8754 1975
2 Austria Male IN 9695 1976
3 Austria Male OUT 17977 1974
4 Austria Male OUT 12271 1975
5 Austria Male OUT 9899 1976
...
请提供一份报告。在这里,这意味着以文本形式提供数据,而不是图像/链接。另请参见。@jpp在本例中,我不需要发布数据帧。我可以更新这个问题,关键是我们很多人喜欢测试我们的解决方案。不幸的是,我们中的许多人也懒得做最耗时的工作,即从头开始构建数据帧。@jpp是正确的。然而,我不会把它描述为懒惰,而是希望尊重我们的时间。给我们提供他们正在处理的数据所需的时间远远少于我们制作数据所需的时间。此外,OP提供的数据是数据。我们制作的数据可能代表OP使用的内容。如果我们的猜测是错误的,那么这就更浪费时间了。我找不到粘贴数据帧的最佳方法。我已经对它进行了简化,但我认为我应该将其发布为JSON格式。我想链接到这个文件会更好。把你的想法告诉我。请提供一个答案。在这里,这意味着以文本形式提供数据,而不是图像/链接。另请参见。@jpp在本例中,我不需要发布数据帧。我可以更新这个问题,关键是我们很多人喜欢测试我们的解决方案。不幸的是,我们中的许多人也懒得做最耗时的工作,即从头开始构建数据帧。@jpp是正确的。然而,我不会把它描述为懒惰,而是希望尊重我们的时间。给我们提供他们正在处理的数据所需的时间远远少于我们制作数据所需的时间。此外,OP提供的数据是数据。我们制作的数据可能代表OP使用的内容。如果我们的猜测是错误的,那么这就更浪费时间了。我找不到粘贴数据帧的最佳方法。我已经对它进行了简化,但我认为我应该将其发布为JSON格式。我想链接到这个文件会更好。告诉我你的想法。是的,我发现只有这一种方法明显比
melt
慢,但不是很好的样本,所以不是100%确定。@ApoloRadomer。如果您关心性能,请参阅我的更新。很高兴你有了答案。是的,只有这一个方法显然比我发现的melt
慢,但不是很好的样本,所以不是100%确定。@ApoloRadomer。如果您关心性能,请参阅我的更新。很高兴你有你的答案。
df1 = (df.ffill()
.melt(id_vars=['Country','Gender','Direction'],var_name="Date", value_name='Value')
.sort_values(['Country', 'Gender','Direction'])
.reset_index(drop=True))
print (df1)
Country Gender Direction Date Value
0 Austria Female IN 1974 8541
1 Austria Female IN 1975 6465
2 Austria Female IN 1976 6447
3 Austria Female OUT 1974 8450
4 Austria Female OUT 1975 7190
5 Austria Female OUT 1976 6288
6 Austria Male IN 1974 13728
7 Austria Male IN 1975 8754
8 Austria Male IN 1976 9695
9 Austria Male OUT 1974 17977
10 Austria Male OUT 1975 12271
11 Austria Male OUT 1976 9899
12 Austria Total IN 1974 22269
13 Austria Total IN 1975 15219
14 Austria Total IN 1976 16142
15 Austria Total OUT 1974 26427
16 Austria Total OUT 1975 19461
17 Austria Total OUT 1976 16187
18 Belgium Female IN 1974 2105
19 Belgium Female IN 1975 2022
20 Belgium Female IN 1976 2057
21 Belgium Female OUT 1974 2100
22 Belgium Female OUT 1975 2113
23 Belgium Female OUT 1976 2004
24 Belgium Male IN 1974 2412
25 Belgium Male IN 1975 2245
26 Belgium Male IN 1976 2296
27 Belgium Male OUT 1974 2800
28 Belgium Male OUT 1975 2490
29 Belgium Male OUT 1976 2413
30 Belgium Total IN 1974 4517
...
...
df.ffill().set_index(
['Country', 'Gender', 'Direction']
).rename_axis('Year', 1).stack().reset_index(name='Value')
Country Gender Direction Year Value
0 Austria Male IN 1974 13728
1 Austria Male IN 1975 8754
2 Austria Male IN 1976 9695
3 Austria Male OUT 1974 17977
4 Austria Male OUT 1975 12271
5 Austria Male OUT 1976 9899
...
def cstm_ffill(s):
i = np.flatnonzero(s.notna())
i = np.concatenate([[0], i, [len(s)]])
d = np.diff(i)
a = s.values[i[:-1].repeat(d)]
return a
def cstm_melt(df):
c = cstm_ffill(df.Country)
g = cstm_ffill(df.Gender)
d = cstm_ffill(df.Direction)
y = df.columns[3:].values
k = len(y)
i = np.column_stack([c, g, d])
v = np.column_stack([*map(df.get, y)]).ravel()
df_ = pd.DataFrame(
np.column_stack([i.repeat(k, axis=0), v, np.tile(y, len(i))]),
columns=['Country', 'Gender', 'Direction', 'Year', 'Value']
)
return df_
cstm_melt(df)
Country Gender Direction Year Value
0 Austria Male IN 13728 1974
1 Austria Male IN 8754 1975
2 Austria Male IN 9695 1976
3 Austria Male OUT 17977 1974
4 Austria Male OUT 12271 1975
5 Austria Male OUT 9899 1976
...