webentwicklung-frage-antwort-db.com.de

kann nicht mit flexiblem Typ reduzieren

Ich habe diesen Datensatz:

           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

Ich möchte die Summe der 5 Spiele für jeden Spieler berechnen.

Das ist mein 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)

Ich hatte den Fehler "kann nicht mit flexiblem Typ reduzieren". Ich bin wirklich sehr neu in Python und ich brauche deine Hilfe.

Vielen Dank

5
chamscab

Erwägen Sie die Verwendung von Pandas-Modul :

import pandas as pd

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

Resultierender Datenrahmen:

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

Summe:

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

Die Komplikation bei der Verwendung von numpy besteht darin, dass es zwei Fehlerquellen (und zu lesende Dokumentation) gibt, nämlich Python selbst sowie numpy.

Ich glaube, Ihr Problem hier ist, dass Sie mit einem sogenannten strukturierten (numpy) -Array arbeiten. 

Betrachten Sie das folgende Beispiel:

>>> 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

Nun wähle ich zuerst die Daten aus, die ich verwenden möchte:

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

Welches war es, was ich wollte.

Vielleicht möchten Sie pandas (Python-Bibliothek) verwenden oder die Sprache in R ändern.


Persönliche Meinungen

Auch wenn "numpy" sicherlich eine mächtige Bibliothek ist, verzichte ich immer noch darauf, sie für Datenwissenschaften und andere "Aktivitäten" zu verwenden, bei denen das Programm auf "flexiblen" Datentypen ausgelegt ist. Persönlich verwende ich numpy, wenn ich etwas brauche, um schnell und wartungsfähig zu sein (es ist leicht, "Code für die Zukunft" zu schreiben), aber ich habe keine Zeit, ein C-Programm zu schreiben.

Was Pandas betrifft, ist es für uns "Python-Hacker" bequem, weil es sich um "R-Datenstrukturen, die in Python implementiert sind", während "R" (offensichtlich) eine völlig neue Sprache ist. Ich persönlich benutze R, da ich Pandas für eine rasche Entwicklung halte, was es schwierig macht, "Code mit Blick auf die Zukunft" zu schreiben.


Wie in einem Kommentar vorgeschlagen (@jorijnsmit glaube ich), besteht keine Notwendigkeit, große Abhängigkeiten wie Pandas für "einfache" Fälle einzuführen. Das minimalistische Beispiel, das mit Python 2 und 3 kompatibel ist, verwendet "typische" Python-Tricks, um die Daten in Frage zu stellen.

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:])) )

Die Ausgabe wäre:

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

Sie können ein strukturiertes Array weiterhin verwenden, solange Sie sich mit den dtypes vertraut machen. Da Ihr Datensatz extrem klein ist, kann das folgende Beispiel als Beispiel für die Verwendung von numpy in Verbindung mit Listenverständnissen dienen, wenn Ihr dtype einheitlich ist, jedoch einen Namen hat

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)]

In diesem Beispiel wäre es sehr schwierig, jede Summe für jeden Spaltennamen einzeln zu erhalten. An diesem Punkt ist das ... a [i] für i in nms-Bit hilfreich, da die Liste der Namen mit nms = a.dtype.names ..__ abgerufen wurde. Da Sie eine "Summe" ausführen, möchten Sie sie einschränken die Summation nur zu Ganzzahl- und Flottatypen, daher der a [i] .dtype.Kind-Teil.

Das Summieren nach Zeilen ist genauso einfach, aber Sie werden feststellen, dass ich diese Syntax nicht verwendet habe, aber eine etwas andere, um die Fehlermeldung zu vermeiden

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

Möglicherweise werden "flexible" Datentypen nicht ihrem Namen gerecht. Sie können also trotzdem mit strukturierten und erneuten Arrays arbeiten, wenn dies der Fall ist, in dem Ihre Daten verwendet werden Ändern von Datentypen entsprechend Ihrem Zweck. Da Ihr Datentyp beispielsweise alle gleich ist und Sie kein monströses Dataset besitzen, können Sie viele Methoden zum Konvertieren in ein einfaches strukturiertes Array verwenden.

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])

Sie haben also viele Möglichkeiten beim Umgang mit strukturierten Arrays und abhängig davon, ob Sie mit reinem Python, Nummel, Pandas oder Hybrid arbeiten müssen, sollten Sie sich mit allen Optionen vertraut machen.

NACHTRAG

Als Abkürzung habe ich nicht erwähnt, 'Ansichten' von Arrays zu nehmen, die in der Natur strukturiert sind, aber den gleichen D-Typ haben. Im obigen Fall besteht eine einfache Möglichkeit, die Anforderungen für einfache Arrayberechnungen nach Zeile oder Spalte wie folgt zu erstellen: Eine Kopie des Arrays wurde erstellt, ist jedoch nicht erforderlich

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

Du brauchst gar keinen Numpy, mach einfach folgendes:

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