1
votes

Compter les valeurs uniques par ligne (sur l'axe d'index, pas par colonne)

J'ai le tableau suivant:

data['Unique_count'] = data.nunique(axis=1)

Maintenant, je veux compter le nombre de valeurs uniques par ligne et le stocker dans une nouvelle colonne appelée Unique_count

Donc, ma sortie attendue serait:

    A   B   C  Unique_count
0  10  10  10             1
1  20  10  20             2
2  30  20  10             3
3  40  40  40             1
4  50  20  20             2

Je suis familier avec SELECT DISTINCT . Mais ce sont toutes des opérations par colonne. Je ne peux pas comprendre comment compter par ligne en SQL.

Avec le module pandas en Python, ce serait simplement:

WITH data AS (
SELECT 10 AS A, 10 AS B, 10 AS C
UNION ALL
SELECT 20 AS A, 10 AS B, 20 AS C
UNION ALL
SELECT 30 AS A, 20 AS B, 10 AS C
UNION ALL
SELECT 40 AS A, 40 AS B, 40 AS C
UNION ALL
SELECT 50 AS A, 20 AS B, 20 AS C)

SELECT * FROM data;

    A   B   C
0  10  10  10
1  20  10  20
2  30  20  10
3  40  40  40
4  50  20  20


0 commentaires

3 Réponses :


2
votes

Dans SQL Server, utilisez une jointure latérale - apply keyword`:

select t.*, v.unique_count
from t cross apply
     (select count(distinct col) as unique_count
      from (values (t.a), (t.b), (t.c)) v(col)
     ) v;

Une jointure latérale ressemble beaucoup à une sous-requête corrélée dans le de la clause - mais plus générale car la sous-requête peut renvoyer plus d'une colonne et plus d'une ligne.

Cette version fait exactement ce à quoi elle ressemble: elle décolle les colonnes puis utilise count (distinct) pour compter le nombre de valeurs uniques.


0 commentaires

1
votes

Dans MySQL, vous pouvez utiliser la logique conditionnelle:

| A   | B   | C   | unique_count |
| --- | --- | --- | ------------ |
| 10  | 10  | 10  | 1            |
| 20  | 10  | 20  | 2            |
| 30  | 20  | 10  | 3            |
| 40  | 40  | 40  | 1            |
| 50  | 20  | 20  | 2            |

Cela fonctionne parce que MySQL évalue les conditions vrai / faux comme 1/0 dans un contexte numérique (cette fonctionnalité nous évite un long cas ici).

Démo sur DB Fiddle :

select
    t.*,
    1 + (a <> b) + (a <> c and b<>c) unique_count
from data t


5 commentaires

Donc, fondamentalement, les booléens des deux conditions que vous additionnez, non?


@Erfan: oui chaque condition produit 1 en cas de succès (sinon 0), et les valeurs sont ajoutées. Cela vous donne le nombre de valeurs distinctes dans les 3 colonnes.


Je vois, belle approche hors de la boîte!


Généraliser cela à plus de 3 colonnes le rend un peu plus complexe, non?


@Barmar: oui, la complexité de la logique conditionnelle augmente drastiquement avec le nombre de colonnes; votre solution est un meilleur choix s'il y a beaucoup de colonnes.



1
votes

Ajoutez une colonne id au tableau. Ensuite, vous pouvez utiliser UNION pour faire pivoter les colonnes en lignes, puis COUNT (*) pour obtenir les décomptes. Ensuite, joignez-le à la table d'origine.

Notez que vous n'avez pas besoin d'utiliser COUNT (DISTINCT) car UNION DISTINCT supprime les doublons.

WITH data AS (
SELECT 0 AS id, 10 AS A, 10 AS B, 10 AS C
UNION ALL
SELECT 1 AS id, 20 AS A, 10 AS B, 20 AS C
UNION ALL
SELECT 2 AS id, 30 AS A, 20 AS B, 10 AS C
UNION ALL
SELECT 3 AS id, 40 AS A, 40 AS B, 40 AS C
UNION ALL
SELECT 4 AS id, 50 AS A, 20 AS B, 20 AS C)

SELECT t1.*, t2.unique_count
FROM data AS t1
JOIN (
    SELECT id, COUNT(*) AS unique_count
    FROM (
        SELECT id, A AS datum FROM data
        UNION DISTINCT
        SELECT id, B AS datum FROM data
        UNION DISTINCT
        SELECT id, C AS datum FROM data) AS x
    GROUP BY id) AS t2
ON t1.id = t2.id


0 commentaires