1
votes

Comment diviser une trame de données par une valeur scalaire obtenue à partir d'une autre trame de données à l'aide de pandas

J'ai une question simple et rapide. J'ai un dataframe tel que celui-ci

  Column_4 Column_4 
1   102832   79639   
2    50034   21058    
3    38230   18963   
4    34503   14216     
5    34219   11450    

Ce que je veux faire est de diviser les valeurs de chaque colonne par une valeur scalaire dérivée d'un autre dataframe, tel que celui-ci.

    Column_4           Column_4
0     Data               Data
1   102832/103000.0     79639/500.0
2    50034/103000.0     21058/500.0
3    38230/103000.0     18963/500.0
4    34503/103000.0     14216/500.0

Voici donc ce que je veux arriver:

          0         1
0  103000.0     500.0

Je sais que vous pouvez diviser un dataframe par des valeurs scalaires, et même des dataframes par valeurs dans d'autres dataframes (en utilisant l'index pour les faire correspondre); Cependant, je n'ai pas encore trouvé un moyen de diviser une colonne d'une dataframe par une valeur scalaire qui est obtenue à partir d'une autre dataframe en utilisant des pandas comme l'exemple ci-dessus.

Modifier: Il y avait une chaîne dans ma colonne (Data), donc je l'ai supprimée. Ceci est la nouvelle base de données.

  Column_4 Column_4
0     Data     Data
1   102832    79639
2    50034    21058
3    38230    18963
4    34503    14216


0 commentaires

4 Réponses :


1
votes

Vous pouvez convertir la deuxième trame de données en liste et effectuer une division normale (les pandas diffuseront la division dans chaque colonne)

# test data
import pandas as pd
df1 = pd.DataFrame({'a': [1,2,3], 'b': [4,5,6]})
df2 = pd.DataFrame({'c':[7], 'd':[8]})

#df1
#   a  b
#0  1  4
#1  2  5
#2  3  6

#df2
#   c  d
#0  7  8

res = df1[['a','b']]/df2.loc[0,['c','d']].tolist()

print(res)

#          a      b
#0  0.142857  0.500
#1  0.285714  0.625
#2  0.428571  0.750


1 commentaires

Est-il possible d'utiliser les commandes pandas exclusivement (sans avoir à convertir mon dataframe en liste)?



1
votes

S'il n'y a qu'une seule ligne dans votre deuxième df:

df1 = pd.DataFrame({"col1":["data",100,200,300,400],
                    "col2":["data",200,300,400,500]})

df2 = pd.DataFrame({"col1":[100],
                    "col2":[200]})

print (df1.iloc[1:].astype(int)/df2.values)

   col1  col2
0   1.0   1.0
1   2.0   1.5
2   3.0   2.0
3   4.0   2.5


11 commentaires

Quand j'essaye d'obtenir cette erreur: ValueError: Impossible de forcer à DataFrame, la forme doit être (10, 4): donnée (1, 2) ...... ce qui est étrange parce que vous avez un (4,2) et se divisent par un (1, 2) dans cet exemple. Donc si ça marche pour toi ça devrait marcher pour moi aussi


Je m'excuse, j'avais la configuration incorrecte (le nombre de colonnes ne correspondait pas). Avec cela corrigé cependant, j'obtiens cette erreur: TypeError: type (s) d'opérande non pris en charge pour /: 'str' et 'float'


En examinant à nouveau vos données, vous sembliez avoir des données comme valeur de chaîne dans vos colonnes. Si tel est le cas, vous devez ignorer cette colonne. Voir édité ci-dessus.


J'ai donc entièrement supprimé cette ligne. Mais j'obtiens toujours la même erreur


Essayez .astype (int) avant la division, mais je pense que vous devriez probablement passer par votre colonne pour un nettoyage en premier. Il se peut qu'il y ait plus de chaînes dans votre colonne que vous ne le pensez.


Dataframe.drop supprime-t-il réellement la valeur du dataframe? Ou le cache-t-il simplement? Je remarque que mon datatable commence à partir de 1 maintenant au lieu de zéro (ce qui impliquerait qu'ils sont toujours là, mais ne sont plus visibles)


Vous devez spécifier si vous souhaitez le faire sur place en appelant df.drop (..., inplace = True) ou par réaffectation df = df.drop (...) < / code>.


En place répond simplement par aucun. C'est la ligne que j'ai utilisée .drop ([0], axis = 0). Utiliser également .astype (int) a fonctionné, mais je ne comprends tout simplement pas pourquoi il n'a pas lu mes valeurs comme int


Comme je l'ai dit, vous faites soit inplace = True qui modifie votre df en place et renvoie None, soit l'assignez explicitement par df = df.drop ([0], axis = 0). . Voici une bonne lecture de la façon dont le travail sur place.


Je comprends cela, ce que je ne comprends pas, c'est pourquoi j'ai besoin de mettre .astype (int), lorsque mes valeurs sont des entiers et non des chaînes.


drop renvoie une copie du df original qui avait un dtype de object puisque vous aviez une chaîne dedans, vous devez donc le forcer en < code> int .



1
votes

Essayez ceci:

df1 / pd.DataFrame(np.repeat(df2.values, df1.shape[0], axis=0), columns=['A', 'B'])

    A           B
0   0.998369    159.278
1   0.485767    42.116
2   0.371165    37.926
3   0.334981    28.432
df2 = pd.DataFrame([[103000.0, 500.0]])
df2

           0        1
0   103000.0    500.0

Les noms de colonnes doivent être identiques dans les deux tableaux

import pandas as pd
import numpy as np

df1 = pd.DataFrame([[102832, 79639], [50034, 21058], [38230, 18963], [34503, 14216]], columns=['A', 'B'])
df1

    A       B
0   102832  79639
1   50034   21058
2   38230   18963
3   34503   14216

p >


6 commentaires

Cela me fournit cette erreur: TypeError: type (s) d'opérande non pris en charge pour /: 'str' et 'float'


samman, les valeurs de votre première trame de données doivent être au format numérique. Essayez ceci: df1.apply (pd.to_numeric, errors = 'coerce')


J'ai utilisé dataframe.drop pour le supprimer, mais j'obtiens la même erreur


Pouvez-vous voir les deux colonnes avec des types int64 à l'aide de cette commande? df1.dtypes


Ceci est la sortie. Objet Column_4 Objet Column_4 dtype: object


donc c'est pourquoi ne fonctionne pas. Les deux colonnes ont besoin d'un format numérique, c'est-à-dire int64, float64, etc. Pas d'objet. Vérifiez la commande: df1 = df1.apply (pd.to_numeric, errors = 'coerce') Vous devez redéfinir la variable df1



1
votes

Avec votre ensemble de données, vous devez procéder comme suit:

df4['Column_4'][1:].astype(int) / df5['0'][0]                                                                                                                                        
Out[363]: 
1    0.998369
2    0.485767
3    0.371165
4    0.334981


0 commentaires