【问题标题】:pandas: Perform multiple commands with a for looppandas:使用 for 循环执行多个命令
【发布时间】:2016-04-24 13:59:54
【问题描述】:

我有以下数据:

    url='https://raw.githubusercontent.com/108michael/ms_thesis/master/clean_gdp_data_all.csv'

c=pd.read_csv(url, index_col=0)
c = c.loc[(c.GeoName == 'California') & \
           (c.ComponentName == 'Real GDP by state')]
c.head(3)


    GeoName     ComponentName   IndustryClassification  Description     2004    2005    2006    2007    2008    2009    2010    2011    2012    2013    2014
38281   California  Real GDP by state   111-112     Farms   15717   18751   18215   15335   14109   18798   19197   16535   15014   16909   0
38282   California  Real GDP by state   113-115     Forestry, fishing, and related activities   6234    6278    7845    7786    7365    7390    7831    8115    8995    9312    0
38284   California  Real GDP by state   211     Oil and gas extraction  7769    8107    10693   12342   12010   17155   14575   15289   18849   16165   0

我想用 for 循环运行以下代码,但我想每年(2004-2014)都运行它,然后将它们合并在一起,如最后一行代码所示:

    d = c.sort_values('2004', ascending=False).head(10)[['GeoName', \
'IndustryClassification', 'Description', 'ComponentName', '2004' ]]


e = c.sort_values('2005', ascending=False).head(10)[['GeoName', \
'IndustryClassification', 'Description', 'ComponentName', '2005' ]]

crgdp = pd.merge(d,e, how='inner', on=['GeoName', \
'IndustryClassification', 'Description', 'ComponentName'])

【问题讨论】:

  • 为什么您对数据框的引用不断在cd 之间切换?
  • @brittenb:感谢您的评论。我刚刚更新了代码。
  • @MaxU:感谢您的评论!是的,我可以这样做。这个问题有点复杂,我需要为每个GeoName 和每个ComponentName 执行此合并。我每年都单独排序,因为我需要每年排名前 10 的行业。我可以每年将数据分类为 11 个不同的 dfs。我还可以将raw-file 拆分为GeoNameComponentName。但是,我不知道如何用 pandas 很好地做到这一点。
  • @MaxU:我选择设置一个模板来收集每个ComponentName 的所有状态/年份,然后切换出ComponentName;但是,我稍后会将我的所有代码清理到项目中。现在我把结果放在口才上。已经2个多月了,我仍在努力处理我的数据。我还有不到 4 个月的时间。

标签: python for-loop pandas


【解决方案1】:

我认为您不能以您想要的方式执行此操作,因为一行中的所有值都是“连接的”并且属于该行。因此,您可以按一列对 DF 进行排序,这将对所有具有所有相应值的行进行重新排序,但是下次当您对另一列进行排序时 - 您将失去第一列中的排序顺序,依此类推...

在以下示例中查看索引值和ab 列中的值:

In [16]: df
Out[16]:
   a  b  c
0  0  7  1
1  6  6  0
2  7  4  5

In [17]: df.sort_values(by='a', ascending=False)
Out[17]:
   a  b  c
2  7  4  5
1  6  6  0
0  0  7  1

In [18]: df.sort_values(by='b', ascending=False)
Out[18]:
   a  b  c
0  0  7  1
1  6  6  0
2  7  4  5

In [19]: df.sort_values(by=['a','b'], ascending=False)
Out[19]:
   a  b  c
2  7  4  5
1  6  6  0
0  0  7  1

注意: 我们如何对数据进行排序并不重要,每一行中的所有值都相互“绑定”到它们的索引。

因此,您可以按ab['a','b'] 对您的DF 进行排序,但在这种情况下,您的b 列将不会单调递减。

查看您的数据 - 如果您按“合并”列对数据进行分组并检查重复项,您会发现您没有任何重复项:

In [132]: c.groupby(['GeoName', 'IndustryClassification', 'Description', 'ComponentName']).size().nlargest(3)
Out[132]:
GeoName     IndustryClassification  Description       ComponentName
California  ...                     Federal civilian  Real GDP by state    1
                                    Federal military  Real GDP by state    1
                                    State and local   Real GDP by state    1
dtype: int64

它表明每个组正好有一行。因此,在合并所有行后将保持不变,因为您可以将 ['GeoName', 'IndustryClassification', 'Description', 'ComponentName'] 列视为主键(即唯一标识符)。

这是一个例子:

In [125]: c.query("GeoName == 'California' and IndustryClassification == '111-112' and Description == 'Farms' and ComponentName == 'Real GDP by s
tate'")
Out[125]:
          GeoName      ComponentName IndustryClassification Description  \
38281  California  Real GDP by state                111-112       Farms

          2004     2005     2006     2007     2008     2009     2010     2011  \
38281  15717.0  18751.0  18215.0  15335.0  14109.0  18798.0  19197.0  16535.0

          2012     2013  2014
38281  15014.0  16909.0   0.0

【讨论】:

  • 谢谢 MaxU。我明白你对排序问题的意思。某些行业总是会出现缺失值,因为它们不是每年都在“前 10 名”中(这也是我选择 10 而不是较小的子部分的原因)。我担心的是,如果我只排序一年(或两年),并且因为我正在控制“顶级行业”(以每个州的 GDP 贡献衡量)对“行业相关法案赞助”的影响',可能会提出问题'这个行业是每年的最大贡献者'。
  • 不过,您的帖子很有帮助。我只需要对Real GDP 进行排序,然后我就可以使用包含相关部门的group by。所以,你再次为我的进步做出了贡献。谢谢!
  • @MichaelPerdue,如果我正确理解您的任务,您可以每年或全年单独执行,但使用 unpivoted 数据会更容易, 国际海事组织
  • @MichaelPerdue,如果你想取消你的c DF:pd.melt(c, id_vars=['GeoName', 'IndustryClassification', 'Description', 'ComponentName'], value_vars=c.filter(like='200').columns.tolist(), var_name='year', value_name='GDP')`
  • @MichaelPerdue,通过您提出的问题可以很容易地看到您的巨大进步 :)
【解决方案2】:

给你,它会帮助你前进:

import pandas as pd

url='https://raw.githubusercontent.com/108michael/ms_thesis/master/clean_gdp_data_all.csv'
c=pd.read_csv(url, index_col=0)
d = c.loc[(c.GeoName == 'California') & (c.ComponentName == 'Real GDP by state')]
for y1, y2 in zip(c.columns[4:], c.columns[5:]):
    d1 = d.sort_values(y1, ascending=False).head(10)[['GeoName','IndustryClassification', 'Description', 'ComponentName', y1 ]]
    e1 = d.sort_values(y2, ascending=False).head(10)[['GeoName','IndustryClassification', 'Description', 'ComponentName', y2 ]]
    crgdp = pd.merge(d1,e1, how='inner', on=['GeoName','IndustryClassification', 'Description', 'ComponentName'])
    crgdp.to_csv('{0}-{1}.csv'.format(y1,y2), index=False)

【讨论】:

  • 感谢您的意见和建议!我要看看我能用这个做什么:)
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 2017-05-11
  • 1970-01-01
  • 2014-12-30
  • 1970-01-01
  • 2012-06-26
  • 2015-06-20
  • 2015-12-12
相关资源
最近更新 更多