Strona główna Polish Python Coders Group
   Strona główna   Pomoc Zaloguj się Rejestracja  
Witamy, Gość. Zaloguj się lub zarejestruj.
Czy dotarł do Ciebie email aktywacyjny?

Zaloguj się podając nazwę użytkownika, hasło i długość sesji

Aktualności: PyData Warsaw 2017, 19-20 października - konferencja Data Science
Szukaj Szukaj
Strony: [1]   Do dołu
Drukuj
Wątek: Współczynnik korelacji Pearsona  (Przeczytany 134 razy)
« : 16:45 14/11/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 22


Zadanie 3 do zrobienia(załącznik)
Kod
import math
def Pearson(x,y):
if len(x)==len(y):
x,y=[float(i) for i in x],[float(i) for i in y]
n,l,m1,m2=len(x),0,0,0
x0,y0=(sum(x)/n),(sum(y)/n)
 
for i in range(n):
l+=(x[i]-x0)*(y[i]-y0)
m1+=((x[i]-x0)**2)
m2+=((y[i]-y0)**2)
return l/(math.sqrt(m1)*math.sqrt(m2))
else:
raise ValueError('Listy muszą być jednakowej długości')
 
x=list(input('Podaj pierwszą listę ').split())
y=list(input('Podaj drugą listę ').split())
print(Pearson(x,y))

I znów pytanie czy da się to uprościć Smutny ? Proszę o pomoc, z góry dzięki Uśmiech
Zapisane
« Odpowiedz #1 : 18:16 14/11/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 14
Płeć: Mężczyzna
Wiadomości: 130


Na przykład:
Kod
def Pearson(x,y):
if len(x)==len(y):
n = len(x)
x0, y0=(sum(x)/n), (sum(y)/n)
 
funct = lambda L, arg2: sum([(arg1-arg2)**2 for arg1 in L])**0.5
return sum([(xi-x0)*(yi-y0) for xi, yi in zip(x,y)])/(funct(x, x0)*funct(y, y0))
else:
raise ValueError('Listy muszą być jednakowej długości')
 
x=[float(i) for i in input('Podaj pierwszą listę ').split()]
y=[float(i) for i in input('Podaj drugą listę ').split()]
print(Pearson(x,y))
Albo mniej skomplikowany sposób z użyciem zip'a:
Kod
def Pearson(x,y):
if len(x)==len(y):
l, m1, m2 = 0,0,0; n = len(x)
x0, y0=(sum(x)/n), (sum(y)/n)
 
for xi, yi in zip(x, y):
l+=(xi-x0)*(yi-y0)
m1+=((xi-x0)**2)
m2+=((yi-y0)**2)
return l/(math.sqrt(m1)*math.sqrt(m2))
else:
raise ValueError('Listy muszą być jednakowej długości')
 
x=[float(i) for i in input('Podaj pierwszą listę ').split()]
y=[float(i) for i in input('Podaj drugą listę ').split()]
print(Pearson(x,y))

Jakby się postarać to wystarczy jedna linijka z rekurencją. Ale minus jest taki że po kilku dniach nawet jako autor zastanawiasz się co do cholery ty tam właśnie napisałeś ;P.
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #2 : 18:25 14/11/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 14
Płeć: Mężczyzna
Wiadomości: 130


W sumie, jako ciekawostka, bez rekurencji, ale można skompresować te lambdę w zmiennej funct, tylko pytanie po co ;d
Kod
def Pearson(x,y):
funct = lambda L, arg2: sum([(arg1-arg2)**2 for arg1 in L])**0.5
return sum([(xi-(sum(x)/len(x)))*(yi-(sum(y)/len(y))) for xi, yi in zip(x,y)])/(funct(x, (sum(x)/len(x)))*funct(y, (sum(y)/len(y)))) if len(x)==len(y) else ValueError('Listy muszą być jednakowej długości')
 
x=[float(i) for i in input('Podaj pierwszą listę ').split()]
y=[float(i) for i in input('Podaj drugą listę ').split()]
print(Pearson(x,y))/code]
 
I tak jest już nieczytelne.
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #3 : 18:31 14/11/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 22


dobra nie miałem tego na wykładzie, jakaś magia Chichot. a moglibyście zerknąć na zad 4 ? Chodzi mi o podpunkt a), chciałem zrobić rekurencyjnie, a wyskakuje RecursionError
Kod
def Podzielnosc(n):
tab,suma=[],0
for i in reversed(x):
tab+=[int(i)]
for i in range(0,len(tab)):
suma+=tab[i]*(3**i)
if suma==7:
return True
else:
Podzielnosc(str(suma))
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))
nie wiem o co chodzi Chichot
Zapisane
« Odpowiedz #4 : 20:08 14/11/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 14
Płeć: Mężczyzna
Wiadomości: 130


dobra nie miałem tego na wykładzie, jakaś magia Chichot.
zip'a warto się nauczyć, podstawowych generatorów również, bardzo ułatwiają robotę. Ale POD (pyramid of doom) to tylko jak jesteś fanboy'em pythona xP. W innych językach z reguły takich cudów nie zrobisz - dlatego nauka takich rozwiązań jest mało uniwersalna.

Co do zadania, najprościej z rekurencją:
Kod
def division_by(num, divi):
   if num==divi: return true;
   else if num < divi: return false;
   else: division_by(num-divi, divi);

W ten sposób możesz sprawdzić podzielność przez dowolną liczbę bez wykonywania dzielenia Uśmiech.

@EDIT: Oczywiście są też specjalne zasady podzielności które masz w zadaniach, ale przyznam szczerze że nie rozumiem tych indeksów górnych/dolnych, więc nie jestem w stanie pomóc w sposób optymalizacyjny :s
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #5 : 21:27 14/11/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 22


chodzi o to że dla przykładu mając liczbe 315 to jest to (5*10^0)+(1*10^1)+(3*10^2) czyli jest to suma a(i)*10^i gdzie a=[3,1,5]  i jest z range(0,len(a)).

Teraz dla a [3,1,5] liczby z tego drugiego wzoru  czyli a(i)*3^i czyli to jest (5*3^0)+(1*3^1)+(3*3^2)=35. I teraz bierzemy to 35 i znowu mielimy przez ten wzór i jak wyjdzie nam 7 na końcu to liczba 315 jest podzielna przez 7, a jak coś innego to nie jest Uśmiech Rozumiesz ? Nie wiem jak to zapisać rekurencyjnie
Zapisane
« Odpowiedz #6 : 21:40 14/11/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 22


i chyba to mam
Kod
def Podzielnosc(n):
if int(n)==7 or int(n)==0:
return True
else:
suma,tab=0,[int(i) for i in reversed(n)]
if len(tab)==1:
return False
else:
for i in range(0,len(tab)):
suma+=tab[i]*(3**i)
return Podzielnosc(str(suma))
 
def Podzielnosc1(n):
if int(n)==11 or int(n)==0:
return True
else:
suma,tab=0,[int(i) for i in n]
if len(tab)==1:
return False
else:
for i in range(0,len(tab)):
suma+=tab[i]*((-1)**i)
return Podzielnosc1(str(suma))
 
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))
print(Podzielnosc1(x))
teraz jak to zrobić prościej Chichot
Zapisane
« Odpowiedz #7 : 22:09 14/11/17 »
Guaz Offline
Advanced Python User

Zobacz profil
**

Reputacja: 14
Płeć: Mężczyzna
Wiadomości: 130


Domyślnie indeksowanie masz od zera:
Kod
for i in range(0,len(tab)) == for i in range(len(tab))

Badanie równości zajmuje najwięcej czasu o ile mnie pamięć nie myli.
Kod:
if len(n)==1:
else:
Więc lepiej to zamienić na coś innego:
Kod
if len(n)>1: #tu wykonujesz poprzedni else
else: #tu wykonujesz poprzednie else, w twoim programie nie jest możliwe by argument miał
        #długość zero, czyli był pustym stringiem w wyniku rekurencji, tylko wejście startowemoż

Kod
def Podzielnosc(n):
if int(n)==7 or int(n)==0:
return True
else:
if len(n)==1: return False; #Metoda len również działa dla łańcuchów znaków (metody string)
else:
suma,tab=None,[int(i) for i in reversed(n)] #Nie ma sensu tego generować jeśli n ma jeden znak długości.
suma = str( sum( [ tab[i]*(3**i) for i in range(len(tab)) ] ) ) #A tu generator jest wskazany.
return Podzielnosc(suma)
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))

Bardziej zrozumiała wersja /\

Mniej zrozumiała:
Kod
def Podzielnosc(n):
   if int(n)==7 or int(n)==0: return True;
   return Podzielnosc(str( sum( [ [int(j) for j in reversed(n)][i]*(3**i) for i in range(len(n)) ] ) )) if len(n)>1 else False
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))
 

@Edit:
Zoptymalizowana:
Mniej zrozumiała:
Kod
def Podzielnosc(n):
   if int(n)==7 or int(n)==0: return True;
   return Podzielnosc(str( sum( [ j*(3**i) for i, j in zip(range(len(n)),[int(g) for g in reversed(n)]) ] ) )) if len(n)>1 else False
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))
 
Zapisane

Python 3.5.2 / Mint
« Odpowiedz #8 : 22:45 14/11/17 »
leo9997 Offline
Hello World!

Zobacz profil
*

Reputacja: 2
Wiadomości: 22


Zostawiam tak
Kod
def Podzielnosc(n):
if int(n)==7 or int(n)==0:
return True
else:
if len(n)==1:
return False
else:
suma,tab=None,[int(i) for i in reversed(n)]
suma=str(sum([tab[i]*(3**i) for i in range(len(tab))]))
return Podzielnosc(suma)
 
def Podzielnosc1(n):
if int(n)==11 or int(n)==0:
return True
else:
if len(n)==1:
return false
else:
suma,tab=None,[int(i) for i in n]
suma=(sum([tab[i]*((-1)**i) for i in range(len(tab))]))
if suma>=0:
return Podzielnosc1(str(suma))
else:
return False
 
x=str(input('Podaj liczbę naturalną '))
print(Podzielnosc(x))
print(Podzielnosc1(x))

Tyle kumam Chichot
Zapisane
Strony: [1]   Do góry
Drukuj
Skocz do:  

© 2007 - 2017 Polish Python Coders Group
Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines | Theme by PixelSlot