迭代数据帧中的行以将值与值进行比较

时间:2017-01-21 21:12:40

标签: python pandas iteration

我有一个大型的pandas数据帧df,其中包含犯罪统计数据。列是犯罪类别(即ARSON,ASSAULT,BAD CHECKS,GRAND THEFT等)。行是犯罪发生的地址。

每个单元格中的值是每个犯罪类别在该地址发生的次数。

我需要编写一个迭代hte数据帧每一行的函数,将值与每个类别的MEAN犯罪数量进行比较,然后只识别那些犯罪数量超过均值的地址。

到目前为止,这是我的代码:

import pandas as pd
import csv
crimeData = open("crimeData.csv")
df = pd.read_csv('crimeData.csv')
df = df.set_index ('Address')
mean = df.mean(axis=0)
#this gives me the mean for each Crime Category
for index, row in df.iterrows():
    if row > mean:
        print (index)

这不起作用。我收到以下错误:

ValueError:系列的真值是不明确的。使用a.empty,a.bool(),a.item(),a.any()或a.all()。

我哪里错了?我怎样才能a)确定每个地址的哪些犯罪类别比平均数更多,以及b)将地址以及超出平均数的犯罪类别打印到列表中?

5 个答案:

答案 0 :(得分:4)

你说row > mean的地方出了问题,这是将一个系列与一个系列进行比较,并会返回一系列真实和虚假的[True, False, False, True] ,它是错误的,因为你问这是真还是假,当然,它可以是两者。

您可以将解决方案更改为:

...
mean = df.mean(0)

for index, row in df.iterrows():
    print(index, list(df.columns[row > mean]))

然而,更好的方法是避免使用iterrows迭代行。 您可以通过以下方式相对简洁地完成此操作:

...
df.set_index('Address', inplace=True)

df[df > df.mean(0)].notnull().apply(lambda x: ', '.join(df.columns[x]),axis=1)

第一部分df[df > df.mean(0)]生成一个数据帧,用null替换小于均值的任何值。

.notnull()部分将空值转换为False,将大于均值的值转换为True。

然后apply部分获取列标题并将True或False值应用于它们,删除False列标题,最后我们连接' True'标题为每个地址的逗号分隔列表。

答案 1 :(得分:2)

IIUC你可以这样做:

project
|-app
  |-component1
    |-<angular component files>
  |-helpers
    |-helper1
      |-<plain typescript file>
|-node_modules

答案 2 :(得分:2)

<强> crimeData.csv

Address         Arson   Burglary  Assault  Murder
Lennon Rd       1       5         3        0
Starr Avenue    2       2         7        0
Harrison Lane   3       1         1        1
import pandas as pd

crimeData = open("crimeData.csv")
df = pd.read_csv('crimeData.csv')
df = df.set_index ('Address')
mean = df.mean()

# You can do the evaluation as simply as this...
exceeded = df[df > mean]
print(exceeded)

               Arson  Burglary  Assault  Murder
Address                                        
Lennon Rd        NaN       5.0      NaN     NaN
Starr Avenue     NaN       NaN      7.0     NaN
Harrison Lane    3.0       NaN      NaN     1.0

发表评论......

for _, row in exceeded.iterrows():
    print(row.name, ":", " ".join(row.dropna().axes[0].values))

答案 3 :(得分:1)

meanpandas.core.series.Series类型的对象。您正在将另一个Series对象rowmean进行比较,这就像说&#34;此Series是否大于此Series?&# 34;这就是为什么异常说这种比较是不明确的。&#34;尝试这样的事情(完成模拟数据,因为没有提供):

df = pd.DataFrame({'A': [1,2,3,4,5], 'B': [5,4,3,4,5], 'C': [6,7,8,9,10]})
mean = df.mean(axis = 0)

# This will give you all of the rows in `df` that are above the average for that crime statistic
for col in df.columns:
    higher_than_mean = df[df[col] > mean[col]][col]

每列的higher_than_mean示例(犯罪统计数据):

3    4
4    5
Name: A, dtype: int64
0    5
4    5
Name: B, dtype: int64
3     9
4    10
Name: C, dtype: int64

答案 4 :(得分:1)

请注意:
这是一个矢量化解决方案,不需要任何循环。 @MaxU还提供了一个矢量化解决方案,用于识别可能超过任何类别平均值的地址。

考虑下面模拟的数据框crimeData

crime_cats = ['ARSON', 'ASSAULT', 'BAD CHECKS', 'GRAND THEFT']
addresses = ['addr_{}'.format(i) for i in range(10)]
crimeData = pd.DataFrame(
    np.random.choice(np.arange(5), size=(10, 4), p=(.6, .1, .1, .1, .1)),
    addresses, crime_cats
)

crimeData

enter image description here

默认情况下,crimeData.mean()计算每列的平均值。默认情况下,当我们将数据框与系列进行比较时,它会逐行比较它们,将系列索引与列标签对齐。这是一个数据框,其中特定地址的犯罪大于犯罪类型的平均值,否则为零。

crime_gt_avg = (crimeData > crimeData.mean()).astype(np.uint8)
crime_gt_avg

enter image description here