web-dev-qa-db-fra.com

ne peut pas effectuer réduire avec le type flexible

J'ai cet ensemble de données:

           Game1    Game2   Game3   Game4     Game5

Player1       2        6        5       2        2

Player2       6        4        1       8        4

Player3       8        3        2       1        5

Player4       4        9        4       7        9

Je veux calculer la somme des 5 jeux pour chaque joueur .

Ceci est mon code:

import csv
f=open('Games','rb')
f=csv.reader(f,delimiter=';')
lst=list(f)
lst
import numpy as np
myarray = np.asarray(lst)
x=myarray[1,1:] #First player
y=np.sum(x)

J'ai eu l'erreur "impossible d'effectuer réduire avec un type flexible". Je suis vraiment très novice en python et j'ai besoin de votre aide.

Je vous remercie

5
chamscab

Pensez à utiliser le module Pandas :

import pandas as pd

df = pd.read_csv('/path/to.file.csv', sep=';')

DataFrame résultant:

In [196]: df
Out[196]:
         Game1  Game2  Game3  Game4  Game5
Player1      2      6      5      2      2
Player2      6      4      1      8      4
Player3      8      3      2      1      5
Player4      4      9      4      7      9

Somme:

In [197]: df.sum(axis=1)
Out[197]:
Player1    17
Player2    23
Player3    19
Player4    33
dtype: int64

In [198]: df.sum(1).values
Out[198]: array([17, 23, 19, 33], dtype=int64)
0
MaxU

La complication liée à l’utilisation de numpy est qu’on a deux sources d’erreur (et une documentation à lire), à ​​savoir python lui-même et numpy.

Je pense que votre problème ici est que vous travaillez avec un tableau dit structuré (numpy)

Prenons l'exemple suivant:

>>> import numpy as np
>>> a = np.array([(1,2), (4,5)],  dtype=[('Game 1', '<f8'), ('Game 2', '<f8')])
>>> a.sum()
TypeError: cannot perform reduce with flexible type

Maintenant, je sélectionne d'abord les données que je veux utiliser:

>>> import numpy as np
>>> a = np.array([(1,2), (4,5)],  dtype=[('Game 1', '<f8'), ('Game 2', '<f8')])
>>> a["Game 1"].sum()
5.0

C'est ce que je voulais.

Peut-être envisageriez-vous d’utiliser pandas (bibliothèque python) ou de changer la langue en R .


Opinions personnelles

Même si "numpy" est certainement une puissante bibliothèque, j'évite néanmoins de l'utiliser pour la science des données et d'autres "activités" dans lesquelles le programme est conçu autour de types de données "flexibles". Personnellement, j'utilise numpy lorsque j'ai besoin de quelque chose pour être rapide et facile à maintenir (il est facile d'écrire du "code pour l'avenir"), mais je n'ai pas le temps d'écrire un programme en C.

Pour ce qui est de Pandas, cela nous convient comme "hackers Python" car ce sont "des structures de données R implémentées en Python", alors que "R" est (évidemment) un langage entièrement nouveau. Personnellement, j'utilise R, car j'estime que les pandas évoluent rapidement, ce qui rend difficile la rédaction de "code pour le futur".


Comme suggéré dans un commentaire (@jorijnsmit je crois), il n'est pas nécessaire d'introduire de grandes dépendances, telles que les pandas, pour les cas "simples". L'exemple minimaliste ci-dessous, compatible à la fois avec Python 2 et 3, utilise des astuces "typiques" de Python pour masquer les données de la question.

import csv

## Data-file
data = \
'''
       , Game1, Game2,   Game3,   Game4,   Game5
Player1,  2,    6,       5,       2,     2
Player2,  6,      4 ,      1,       8,      4
Player3,  8,     3 ,      2,    1,     5
Player4,  4,  9 ,   4,     7,    9
'''

# Write data to file
with open('data.csv', 'w') as FILE:
    FILE.write(data)

print("Raw data:")
print(data)

# 1) Read the data-file (and strip away spaces), the result is data by column:
with open('data.csv','rb') as FILE:
  raw = [ [ item.strip() for item in line] \
                      for line in list(csv.reader(FILE,delimiter=',')) if line]

print("Data after Read:")
print(raw)

# 2) Convert numerical data to integers ("float" would also work)
for (i, line) in enumerate(raw[1:], 1):
    for (j, item) in enumerate(line[1:], 1):
        raw[i][j] = int(item)

print("Data after conversion:")
print(raw)

# 3) Use the data...
print("Use the data")
for i in range(1, len(raw)):
  print("Sum for Player %d: %d" %(i, sum(raw[i][1:])) )

for i in range(1, len(raw)):
  print("Total points in Game %d: %d" %(i, sum(list(Zip(*raw))[i][1:])) )

La sortie serait:

Raw data:

       , Game1, Game2,   Game3,   Game4,   Game5
Player1,  2,    6,       5,       2,     2
Player2,  6,      4 ,      1,       8,      4
Player3,  8,     3 ,      2,    1,     5
Player4,  4,  9 ,   4,     7,    9

Data after Read:
[['', 'Game1', 'Game2', 'Game3', 'Game4', 'Game5'], ['Player1', '2', '6', '5', '2', '2'], ['Player2', '6', '4', '1', '8', '4'], ['Player3', '8', '3', '2', '1', '5'], ['Player4', '4', '9', '4', '7', '9']]
Data after conversion:
[['', 'Game1', 'Game2', 'Game3', 'Game4', 'Game5'], ['Player1', 2, 6, 5, 2, 2], ['Player2', 6, 4, 1, 8, 4], ['Player3', 8, 3, 2, 1, 5], ['Player4', 4, 9, 4, 7, 9]]
Use the data
Sum for Player 1: 17
Sum for Player 2: 23
Sum for Player 3: 19
Sum for Player 4: 33
Total points in Game 1: 20
Total points in Game 2: 22
Total points in Game 3: 12
Total points in Game 4: 18
2
Sigve Karolius

Vous pouvez toujours utiliser un tableau structuré tant que vous vous familiarisez avec les types. Étant donné que votre ensemble de données est extrêmement petit, les exemples suivants peuvent servir d'exemple d'utilisation de numpy avec des listes compréhensives lorsque votre type de type est uniforme mais nommé.

dt = [('Game1', '<i4'), ('Game2', '<i4'), ('Game3', '<i4'),
      ('Game4', '<i4'), ('Game5', '<i4')]
a = np.array([(2, 6, 5, 2, 2),
              (6, 4, 1, 8, 4),
              (8, 3, 2, 1, 5),
              (4, 9, 4, 7, 9)], dtype= dt)

nms = a.dtype.names
by_col = [(i, a[i].sum()) for i in nms if a[i].dtype.kind in ('i', 'f')]
by_col
[('Game1', 20), ('Game2', 22), ('Game3', 12), ('Game4', 18), ('Game5', 20)]

by_row = [("player {}".format(i), sum(a[i])) for i in range(a.shape[0])]
by_row
[('player 0', 17), ('player 1', 23), ('player 2', 19), ('player 3', 33)]

Dans cet exemple, il serait très difficile d’obtenir chaque somme individuellement pour chaque nom de colonne. C’est là que le bit ... a [i] for i in nms est utile car la liste des noms a été récupérée par nms = a.dtype.names . Puisque vous faites une "somme", vous voulez restreindre la sommation aux seuls types entier et float, d'où la partie a [i] .dtype.kind.

Résumer par rangée est tout aussi facile, mais vous remarquerez que je n'ai pas utilisé cette syntaxe, mais une syntaxe légèrement différente pour éviter le message d'erreur.

a[0].sum()  # massive failure
....snip out huge error stuff...
TypeError: cannot perform reduce with flexible type
# whereas, this works....
sum(a[0])   # use list/Tuple summation

Les types de données 'flexibles' ne correspondent peut-être pas à leur nom . Vous pouvez donc toujours travailler avec des structures structurées et des recarrays si vos données sont importées de cette manière. Vous pouvez devenir habile à reformater simplement vos données modifier les types en fonction de vos besoins. Par exemple, étant donné que vos types de données sont tous identiques et que vous n'avez pas un ensemble de données monstrueux, vous pouvez utiliser plusieurs méthodes pour convertir en un tableau structuré simple.

b = np.array([list(a[i]) for i in range(a.shape[0])])
b
array([[2, 6, 5, 2, 2],
       [6, 4, 1, 8, 4],
       [8, 3, 2, 1, 5],
       [4, 9, 4, 7, 9]])

b.sum(axis=0)
array([20, 22, 12, 18, 20])

b.sum(axis=1)
array([17, 23, 19, 33])

Vous disposez donc de nombreuses options pour gérer des tableaux structurés et selon que vous devez travailler en python pur, en Numpy, en Pandas ou en un hybride, vous devez vous familiariser avec toutes les options.

ADDENDA

En tant que raccourci, j’ai omis de mentionner la prise de "vues" de tableaux structurés par nature, mais ayant le même type. Dans le cas ci-dessus, un moyen simple de définir les conditions requises pour les calculs de tableau simples par ligne ou par colonne est le suivant ...

b = a.view(np.int32).reshape(len(a), -1)
b
array([[2, 6, 5, 2, 2],
       [6, 4, 1, 8, 4],
       [8, 3, 2, 1, 5],
       [4, 9, 4, 7, 9]])
b.dtype
dtype('int32')

b.sum(axis=0)
array([20, 22, 12, 18, 20])

b.sum(axis=1)
array([17, 23, 19, 33])
1
NaN

Vous n'avez pas besoin de Numpy du tout, faites ceci:

import csv
from collections import OrderedDict

with open('games') as f:
    reader = csv.reader(f, delimiter=';')
    data = list(reader)

sums = OrderedDict()
for row in data[1:]:
    player, games = row[0], row[1:]
    sums[player] = sum(map(int, games))
0
Anthony Perot