Skip to main content

Poker Analysis using Python (numpy and pandas)

In this I did an analysis on poker. I made my own dataset by randomly selecting 7 cards from the dataset. It does not gives the actual results. It is more of a simulation of actual data.


I have used jupyter-notebook for this you can use any IDE according to your liking.

Start by importing the modules.

import pandas as pd
import numpy as np
import random
import time


Then I created a function calculate_hand which takes hand as a list and returns a boolean list with the corresponding values [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]. If the hand has three cards of same value three_of_a_kind will be True, also pair will be True because if a hand has three of a kind, it also has a pair. Highcard always return the high card.

ALL_CARDS_NUM = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, 'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}
ALL_CARDS_NUM_TO_TEXT = {1:'A', 2: '2', 3: '3', 4: '4', 5: '5', 6: '6', 7: '7', 8: '8', 9: '9', 10:'T', 11:'J', 12:'Q', 13:'K', 14:'A'}
FACE_CARDS = {'T': 10, 'J': 11, 'Q': 12, 'K': 13, 'A': 14}

def to_number(card):
    if card[0].isnumeric():
        return int(card[0])
    else:
        return FACE_CARDS[card[0]]
   
   
def is_straight(num):
    all_straights = []
    seqcount = np.zeros(7, dtype=np.int)
   
    for i in range(1,len(num)):
        if ALL_CARDS_NUM[num[i-1]] - ALL_CARDS_NUM[num[i]] == -1:
            seqcount[i] = seqcount[i-1] + 1 
        elif ALL_CARDS_NUM[num[i-1]] == ALL_CARDS_NUM[num[i]]:
            seqcount[i] = seqcount[i-1]

    for x in np.argwhere(seqcount >= 4):
        return (True, seqcount)
   
    try:
        if num[-1] == 'A' and seqcount[num.index('5')] >=3:
            return (True, seqcount)
    except:
        pass
   
    return (False, seqcount)


def count_cards(num):
    ptf = {}
    temp_count = np.zeros(13)
   
    for x in num:
        temp_count[ALL_CARDS_NUM[x]%13 - 1] += 1
   
    for x in np.argwhere(temp_count > 1):
        ptf[ALL_CARDS_NUM_TO_TEXT[x[0] + 1]] = int(temp_count[x[0]])
       
    return ptf

def count_suites(suite):
    suites_array = {'S': [],
                   'C': [],
                   'H': [],
                   'D': []}
       
    for i in range(len(suite)):
        suites_array[suite[i]].append(i)

    for key, value in suites_array.items():
        if len(value) >= 5:
            return value

    return []

def calculate_hand(temp_hand, show = False):
    hand = temp_hand.copy()
    hand.sort(key=to_number)
    num = []
    suite = []
   
    hand_value = {}
   
    for x in hand:       
        num.append(x[0])
        suite.append(x[1])
   
   
   
    #straight
    straight, seq = is_straight(num)
    pairs = count_cards(num)
    flushes = count_suites(suite)
   
    #straignt flush
    straight_flush = False
    straight_flush_sequence = []
   
    if straight and flushes:
        for i in range(len(flushes)-4):
            flush_seq = [num[z] for z in flushes[i:i+5]]
            temp, _ = is_straight(flush_seq)
           
            if temp:
                straight_flush = True
                straight_flush_sequence = flush_seq
   
    #royal flush
    royal_flush = False
   
    if straight_flush:
        if straight_flush_sequence[-1] == 'A':
            royal_flush = True
       
    #pairs
    pair_value = np.asarray([value for _,value in pairs.items()], dtype=np.int)

    #four of a kind
    four_of_a_kind = False
    if np.argwhere(pair_value >= 4).size != 0:
        four_of_a_kind = True
       
   
    #three of a kind
    three_of_a_kind = False
    if np.argwhere(pair_value >= 3).size != 0:
        three_of_a_kind = True

   
    #full house
    full_house = False
    if three_of_a_kind and np.argwhere(pair_value >= 2).size >= 2:
        full_house = True
       
    #flush
    flush = False
    if flushes:
        flush = True
   
    #two pairs
    two_pairs = False
   
    if np.argwhere(pair_value >= 2).size >= 2:
        two_pairs = True
       
    #pairs
    pair = bool(pairs)
   
    #high card
    highcard = num[-1]

    if show:
        print(num, suite)
        print("royal flush:\t\t",royal_flush)
        print("straight flush:\t\t", straight_flush)
        print("four of a kind:\t\t", four_of_a_kind)
        print("full house:\t\t", full_house)
        print("flush:\t\t\t", flush)
        print("straight:\t\t", straight)
        print("three of a kind:\t", three_of_a_kind)
        print("Two pairs:\t\t", two_pairs)
        print("Pair:\t\t\t", pair)
        print("High card: \t\t",highcard)
   
   
    return [royal_flush, straight_flush, four_of_a_kind, full_house, flush, straight, three_of_a_kind, two_pairs, pair, highcard]


The other functions here are the helping functions.

Now you can create your dataset:

card_num = ['A','2','3','4','5','6','7','8','9','T','J','Q','K']
suite = ['S','C','H','D']
main = []

def randCard():
    choosen_num = random.choice(card_num)
    choosen_suite = random.choice(suite)
   
    return str(choosen_num) + choosen_suite

start = time.time()

for i in range(1000000):
    temp = []
    for j in range(7):

        choosen_card = randCard()

        while (choosen_card in temp):
            choosen_card = randCard()

        temp.append(choosen_card)
       
    hand_val = calculate_hand(temp)
   
    try:
        top_val = hand_val.index(True)
    except:
        top_val = 9
   
    temp += hand_val
    temp.append(top_val)
   
    if i%100000 == 0:
        print("Time Elapsed",i,"=", time.time() - start)
   
    main.append(temp)

print("\n\nTotal Time Elapsed =", time.time() - start) 


The dataset is stored in the main variable now convert into a pandas dataframe.

x = pd.DataFrame(data=main, columns=["YC1", "YC2", "F1", "F2", "F3", "R", "T", "royal_flush", "straight_flush", "four_of_a_kind", "full_house", "flush", "straight", "three_of_a_kind", "two_pairs", "pair", "highcard", "top_val" ])

x.head()


Now you can either save your data set in csv format or create new dataset every time you decide to use this.

x.to_csv(file_name,index=False)
 
To read the csv file you can use read_csv function
 
x = pd.read_csv(file_name) 

Now we can start analysing the data. 
 
top_hand_value_dict = {
    0: "royal_flush", 
    1: "straight_flush", 
    2: "four_of_a_kind", 
    3: "full_house", 
    4: "flush", 
    5: "straight",
    6: "three_of_a_kind", 
    7: "two_pairs", 
    8: "pair", 
    9: "highcard" 
}

def calculate_hand_value(data, x1, x2):
    
    print("\nIndividuaized values\n")
    hands = data.loc[((data["YC1"] == x1) & (data["YC2"] == x2)) | ((data["YC1"] == x2) & (data["YC2"] == x1))]
    len_hand = len(hands)
    
    print("Length of the sample: ", len_hand, "\n")

    
    for i in range(9):
        perc_val = 100 * hands[top_hand_value_dict[i]].sum()/len_hand
        print(top_hand_value_dict[i] + ":\t", round( perc_val , 3))
    
    z = hands.loc[:, hands.columns[7:len(hands.columns)-1]].sum(axis = 1)
    print("\nNothing:\t\t" , 100 * len(z.loc[z == 0])/len(z) )
        
def calculate_top_values(data, x1, x2):
    
    print("\nTop Values:\n")
    hands = data.loc[((data["YC1"] == x1) & (data["YC2"] == x2)) | ((data["YC1"] == x2) & (data["YC2"] == x1))]
    len_hand = len(hands)
    
    print("Total number of rows:", len_hand)
    
    l = hands['top_val'].value_counts()
    
    for key, value in dict(l).items():
        print(top_hand_value_dict[key] + ":\t", round( (value/len_hand)*100, 3))
     
calculate_hand_value check the possibility of the value of the hand. x1 and x2 are the cards. 
calculate_top_values check the top value of the hand. x1 and x2 are the cards. 
calculate_hand_value(x, "8S", "8D")
calculate_top_values(x, "QH", "JS")

Use above functions to check outputs.
 
def hand_losing(data, YC1, YC2, delt_card):
    
    print("\nChances of loosing this hand: ")
    
    hand = [YC1, YC2] + delt_card
    
    len_delt_card = len(delt_card)
        
    delt_card_hands = data.loc[ data.iloc[:,0:7].isin(delt_card).sum(axis="columns") >= len_delt_card]

    if delt_card_hands.empty:
        print("Sorry no values present!!! Increase the rows database")
    else:
        
        len_hand = len(delt_card_hands)
    
        hand_val = calculate_hand(hand)

        try:
            top_val = hand_val.index(True)
        except:
            top_val = 9
            
        len_lost =  len(delt_card_hands.loc[data['top_val'] < top_val])
        print("Chances of losing by cards value: ", len_lost)
        
        hand_high_card = ALL_CARDS_NUM[hand_val[9]]

        len_lost_high_val = len(
            delt_card_hands.loc[
                (data['top_val'] == top_val) &
                (data['highcard'].apply(lambda i: ALL_CARDS_NUM[i]) > hand_high_card)
            ]
        )
        
        print("Chances of losing by highcard: ", len_lost_high_val)
        
        unpredicted = len(
            delt_card_hands.loc[
                (data['top_val'] == top_val) &
                (data['highcard'] == hand_val[9])
            ]
        )
        
        print("Unpredicted data: ", unpredicted)
        
        
        print("Chances of losing (w unpredicted): ",
              len_lost + len_lost_high_val, "/",len_hand)
        print("Percentage of losing (w unpredicted): ", 
              round(100 * (len_lost + len_lost_high_val)/len_hand,3))
        
        print("Chances of losing (w/o unpredicted): ", 
              len_lost + len_lost_high_val, "/",(len_hand - unpredicted))
        print("Percentage of losing (w/o unpredicted): ", 
              round(100 * (len_lost + len_lost_high_val)/(len_hand - unpredicted),3))
hand_losing gives the number of times your hand can loose given the dataset.
 
hand_losing(x, "8S", "8D", ["8C", "TS", "TH", "9S", "8H"])
 
You can change the number of cards in the list for turn,flop and river.
 
Hope you liked this. 
 

Comments

Popular posts from this blog

Social Influence: Some tips and tricks

In our previous posts, we have learnt about some of the techniques in Social Psychology. Now in this post I want to tell you about some techniques that you can use in real life to influence people or to protect yourself from being influence by other people and make rash decisions. Some of the tips are: People more likely to help you when you ask them to imagine or predict doing something. Telling some stranger your name first can also be helpful when asking a favour. One can say “Hello, I am ___ and I was wondering whether you do me a favour.” Talking with people is more helpful that talking at people when asking for something/favour. Engaging people in dialogues rather than a monologue. Now I would like to tell you about the most commonly used persuasion techniques. These techniques are: 1.       Foot-in-the-door technique 2.       Door-in-the-face technique 3.       Low-ball technique N...

Obedience to Authority.. Milgram experiment

Obedience is a form of social influence where an individual acts in response to a direct order from another individual, who is usually an authority figure. It is assumed that without such an order the person would not have acted in this way. But this obedience can be harmful in some situations. The most famous example of this can be the Holocaust in Nazi Germany. Do we believe that all of the people in Nazi Germany wanted to kill those six million European Jew? No, but they were bound and ordered by the authorities to do so. This obedience to authority figures is in our nature. This can happen to all of us.  In one of the famous experiment, the nurses were told by the doctor to give a certain medicine to the patients which the nurses didn't know about. Out of 22 nurses which participated 21 gave those medicines to the patients. Now let's talk about the Milgram experiment. It was a series of social psychology experiments conducted by Yale University psychologist Stanl...

Conformity and Asch Experiment

Jump to search According to Wikipedia, Conformity is: Conformity is the act of matching attitudes, beliefs, and behaviors to group norms. Norms are implicit, specific rules, shared by a group of individuals, that guide their interactions with others. People often choose to conform to society rather than to pursue personal desires because it is often easier to follow the path others have made already, rather than creating a new one. In other words, Conformity is basically yielding to group or social pressure. Group pressure can be of many forms like bullying, teasing, criticism etc. Solomon Asch was one of the first scientist that worked on conformity and in turn influenced Miligram experiments . He is best known for his conformity experiments . His main finding was that peer pressure can change opinion and even perception.  Conformity, indicates agreement to the majority, which are brought by a desire to ‘fit in’ or to be liked (normative) or because of a...