Pandas:通过将2列值(复合键)匹配到1列以及另一个数据帧的列标签/索引,在2个数据帧之间映射值

2024-09-28 20:38:19 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题听起来好像以前有人问过,但无法应用或理解我的案例的解决方案,因此问…
我有一个数据帧Main,看起来像这样,有两列topic, cat,有我想要的新的需要的列Value

topic    |   cat   | Value(needed col)
---------------------------------
top1     | cat1    |   0
---------------------------------
top2     | cat3    |   4
---------------------------------
top4     | cat4    |   1

虽然上面的Value列的值位于另一个数据帧Values_df中,其中一些80Rx30C的形式如下:

cat     | top1 | top2 | top3 | top4...top30
-------------------------------------------
cat1    | 0    |  1   | 2    | 2
-------------------------------------------
cat2    | 1    |  1   | 1    | 1
-------------------------------------------
cat3    | 2    |  4   | 3    | 3
-------------------------------------------
cat4    | 5    |  2   | 1    | 1
.
.
cat80   | 2    |  7   | 4    |

我尝试转置Values_df并左键连接,但由于我有多个列,所以无法理解, 我做的另一个尝试是在dictionary中创建一个字典,如下所示: {'cat1': {'top1':0, 'top2':1, 'top3':2, 'top4':2}} 并绘制地图,但仍坚持绘制地图

有什么方法可以帮助我在Main中添加Value


Tags: 数据dftopicvaluemaincatvaluescat1
2条回答

像下面这样的

import pandas as pd

#dummy main data
main_df = pd.DataFrame({
  'topic': ['top1', 'top2', 'top4'],
  'cat': ['cat1', 'cat3', 'cat4'],
})

#dummy values data
values_df = pd.DataFrame({
  'cat': ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6'],
  'top1': [10, 1, 2, 3, 4, 5],
  'top2': [5, 4, 3, 2, 1, 6],
  'top3': [2, 2, 1, 3, 5, 3],
  'top4': [3, 4, 1, 2, 3, 6],
  'top5': [1, 3, 2, 5, 4, 7],
})

meltvalues_df之前,我们需要为values_df快速创建列标题:

cols_label = ['top' + str(x) for x in range(1, 6)]

在您的情况下,range(1, 6)应该是range(1, 31)

融化values_df

values_df = values_df.melt(id_vars=['cat'], value_vars=cols_label)

这将为我们提供以下信息:

enter image description here

然后,合并主值和值:

merged = main_df.merge(values_df, how='left', left_on=['cat', 'topic'], right_on=['cat', 'variable']).drop('variable', axis=1)

以下是最终结果:

enter image description here

您可以通过将Values_df通过^{}熔化来从Values_df进行映射,然后在topic列和cat列通过^{}设置索引,并指定列value(列value^{}生成)

然后,在Main数据帧上,为每一行获取一个topiccat元组,作为一个复合键,用于匹配由^{}创建的映射,如下所示:

mapping = Values_df.melt(id_vars='cat', var_name='topic').set_index(['topic', 'cat'])['value']

Main['Value'] = Main[['topic', 'cat']].apply(tuple, axis=1).map(mapping)

数据输入

Main = pd.DataFrame({'topic': ['top1', 'top2', 'top4'], 'cat': ['cat1', 'cat3', 'cat4']})

  topic   cat
0  top1  cat1
1  top2  cat3
2  top4  cat4


data = {'cat': ['cat1', 'cat2', 'cat3', 'cat4', 'cat80'],
 'top1': [0, 1, 2, 5, 2],
 'top2': [1, 1, 4, 2, 7],
 'top3': [2, 1, 3, 1, 4],
 'top4': [2, 1, 3, 1, 9]}
Values_df = pd.DataFrame(data) 

     cat  top1  top2  top3  top4
0   cat1     0     1     2     2
1   cat2     1     1     1     1
2   cat3     2     4     3     3
3   cat4     5     2     1     1
4  cat80     2     7     4     9

已创建映射:

print(mapping)

topic  cat  
top1   cat1     0
       cat2     1
       cat3     2
       cat4     5
       cat80    2
top2   cat1     1
       cat2     1
       cat3     4
       cat4     2
       cat80    7
top3   cat1     2
       cat2     1
       cat3     3
       cat4     1
       cat80    4
top4   cat1     2
       cat2     1
       cat3     3
       cat4     1
       cat80    9
Name: value, dtype: int64

结果:

print(Main)

  topic   cat  Value
0  top1  cat1      0
1  top2  cat3      4
2  top4  cat4      1

相关问题 更多 >