【问题标题】:Python compute correlation of a single variable between groupsPython计算组之间单个变量的相关性
【发布时间】:2021-02-05 23:20:54
【问题描述】:

我想计算面板数据中两组之间变量“小时”的相关性。具体来说,我想计算 A 组和 B 组与 C 组之间的小时数的相关性。因此最终结果将包含两个数字:corr(hours_A, hours_C) 和 corr(hours_B, hours_C)。

我试过了:

data.groupby('group').corr()

但它给了我每组内“小时”和“其他变量”之间的相关性,但我想要两组之间“小时”变量的相关性。我是 Python 新手,欢迎提供任何帮助!

group year hours other variables
A 2000 2784 567
A 2001 2724 567
A 2002 2715 567
B 2000 2301 567
B 2001 2612 567
B 2002 2489 567
C 2000 2190 567
C 2001 2139 567
C 2002 2159 567

更新:

感谢您回答我的问题! 我最终想出了自己的一些代码,但我的代码并不像提供的答案那么优雅。为了它的价值,我把它贴在这里。

df = df.set_index(['group','year'])
df = df.unstack(level=0)
df.index = pd.to_datetime(df.index).year
df.columns = df.columns.rename(['variables',"group"])
df.xs('hours',  level="variables", axis=1).corr()

索引年份不是相关性所必需的,但如果我想稍后创建数据的横截面,它可能会派上用场。

【问题讨论】:

  • 请从intro tour 重复on topichow to ask。 “告诉我如何解决这个编码问题”不是堆栈溢出问题。我们希望您做出诚实的尝试,然后然后就您的算法或技术提出一个具体的问题。 Stack Overflow 并不打算取代现有的文档和教程。由于您尚未尝试解决方案或研究算法,因此您还没有 Stack Overflow 问题。
  • 感谢您的反馈。我更新了我的问题以包含我尝试过但不起作用的代码。
  • 请提供预期的minimal, reproducible example (MRE)。显示中间结果与您的预期不同的地方。我们应该能够复制并粘贴您的代码的连续块,执行该文件,并重现您的问题以及跟踪问题点的输出。这让我们可以根据您的测试数据和所需的输出来测试我们的建议。
  • 您发布的行不是试图关联您指定的组。正如文档告诉您的那样,它关联给定 DF 的列。
  • 谢谢。刚刚用我的代码附加了一个更新。

标签: python correlation panel-data


【解决方案1】:

也许这不是最好的方法,但我相信这会让你走上自己的路。

import pandas as pd
import numpy as np

data = data[['group', 'year', 'hours']]

data_new = data.set_index(['year', 'group']).unstack(['group'])
final_df = pd.DataFrame(data_new.to_numpy(), columns=['A', 'B', 'C'])

final_df.corr()

我也会留下这个过程来(我认为)为任何希望尝试的人重现您的问题!

import pandas as pd
import numpy as np

data_str = '''A|2000|2784|567
A|2001|2724|567
A|2002|2715|567
B|2000|2301|567
B|2001|2612|567
B|2002|2489|567
C|2000|2190|567
C|2001|2139|567
C|2002|2159|567'''.split('\n')

data = pd.DataFrame([x.split('|') for x in data_str], columns=['group', 'year', 'hours', 'other_variables'])

data['hours'] = data['hours'].astype(int)

【讨论】:

  • 谢谢!我不知道 to_numpy() 方法,很高兴学到新东西。
【解决方案2】:

您可以将列表应用于组,然后转换为系列,转置,然后对数据调用 corr()。

from io import StringIO
import pandas as pd

>>> data = StringIO("""group,year,hours,other,variables
A,2000,2784,567
A,2001,2724,567
A,2002,2715,567
B,2000,2301,567
B,2001,2612,567
B,2002,2489,567
C,2000,2190,567
C,2001,2139,567
C,2002,2159,567""")
>>> df = pd.read_csv(data)
>>> df.groupby('group')['hours'].apply(list).apply(pd.Series).T.corr()

          0         1         2
0  1.000000  0.771752  0.898470
1  0.771752  1.000000  0.972589
2  0.898470  0.972589  1.000000

这是如何工作的? groupby + apply(list) 产生以下内容,这是一个包含三行的系列,每行是三个项目的列表。

A    [2784, 2724, 2715]
B    [2301, 2612, 2489]
C    [2190, 2139, 2159]

apply(pd.Series) 将每一行中的列表转换为一个系列。然后,您必须使用 T 运算符进行转置,以在单个列中获取每个组的数据。

          0     1     2
group
A      2784  2724  2715
B      2301  2612  2489
C      2190  2139  2159

transposed is

group     A     B     C
0      2784  2301  2190
1      2724  2612  2139
2      2715  2489  2159

如果你只想要两个值,那就是

>>> df.groupby('group')['hours'].apply(list).apply(pd.Series).T.corr().iloc[1:3,0].values
array([-0.86594029,  0.86783525])

在此示例中,您使用 iloc 获取第一列中的第二行和第三行(python 索引从零开始),然后使用 Seriesvalues 属性返回一个数组而不是Series.

【讨论】:

  • 感谢您的详细解释!我从来没有想过这样做!
猜你喜欢
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 2019-07-23
相关资源
最近更新 更多