Numpy数组而不是python列表 - 使用nditer从两个1d数组创建一个2d数组

时间:2013-12-20 19:20:29

标签: python numpy

以下代码有效,但尽管付出了一些努力但无法弄清楚如何使用numpy数组(使用nditer)而不是python列表(使用枚举)。

这是一个心理学实验,每个试验呈现四种刺激中的一种,并记录参与者的反应时间。然后通过从两个1d阵列创建2d阵列来计算四种试验类型中的每一种的平均反应时间。

trialTypeData = [3, 0, 2, 1, 1, 0, 2, 3]
Rt = [900, 1200, 1300, 1400, 1100, 1200, 1300, 1400]

RtByTrialType = [0, 0, 0, 0]
meanRtByTrialType = [0, 0, 0, 0]

for trialType in range(0, 4):
    RtByTrialType[trialType] = [Rt[i] for i, x in enumerate(trialTypeData) if x == trialType]
meanRtByTrialType[trialType] = sum(RtByTrialType[trialType])/len(RtByTrialType[trialType])

print "Average latencies by Trialtype:"
print (meanTrialTypeRt)

3 个答案:

答案 0 :(得分:2)

对于此类数据分析,我建议使用pandas代替numpy;它使很多事情变得更容易。在这种情况下,您可以使用groupby(按类型收集项目)然后mean执行此操作:

>>> import pandas as pd
>>> trialTypeData = [3, 0, 2, 1, 1, 0, 2, 3]
>>> Rt = [900, 1200, 1300, 1400, 1100, 1200, 1300, 1400]
>>> df = pd.DataFrame({"Rt": Rt, "type": trialTypeData})
>>> df
     Rt  type
0   900     3
1  1200     0
2  1300     2
3  1400     1
4  1100     1
5  1200     0
6  1300     2
7  1400     3

[8 rows x 2 columns]
>>> df.groupby("type").mean()
        Rt
type      
0     1200
1     1250
2     1300
3     1150

[4 rows x 1 columns]

答案 1 :(得分:1)

请勿使用nditer。有更好的方法:

meanTrialTypeRt = [Rt[trialTypeData == trialType].mean()
                   for trialType in xrange(4)]

对于每种试用类型,这会选择trialTypeData等于trialType的位置,从Rt获取这些位置,并计算平均值。使用NumPy或SciPy统计程序可能有更好的方法来实现这一点,我现在不熟悉或不记得;我正在使用的列表理解是一个很大的红旗,这个例程的运行时间仍然随着试用类型的数量而不必要地增长。

(请注意,RttrialTypeData需要为NumPy数组才能生效。)

答案 2 :(得分:0)

这是另一种方式:

trialTypeData = np.array([3, 0, 2, 1, 1, 0, 2, 3])
Rt = np.array([900, 1200, 1300, 1400, 1100, 1200, 1300, 1400])

meanTrialTypeRt = np.bincount(trialTypeData, Rt) / np.bincount(trialTypeData)

或者,如果您知道每种试验类型的实例数相同:

n_trials = 4
order = trialTypeData.argsort()
RtByTrialType = Rt[order].reshape((n_trials, -1))
meanTrialTypeRt = RtByTrialType.mean(1)

第二种方法可能较慢(或者我没有计时),但是它产生了RtByTrialType数组,如果以后需要它可以使用它。重塑中的-1告诉numpy找出使重塑工作的值应该是什么。